Changing the current input port in racket - scheme

How can I change the input port in racket?
That is, suppose I create a new input port:
(define my-port (open-input-string "this is a test"))
How can I make it so that (current-input-port) returns my-port now?

To add to Chris' answer; the current input port is what's known as a "parameter", which is very approximately a dynamically scoped setting/variable. In general, it's cleaner and more conservative to set the current input port only temporarily, using 'parameterize'. Like this:
(parameterize ([current-input-port my-port])
... do some stuff ...
)
Evaluating this code will cause the input-port to be set for your body code and any code that it calls, but won't "bleed over" into code that's evaluated outside; it will also undo the change on an exceptional or continuation-based exit.

(current-input-port my-port)
Don't do this at the racket REPL! This will cause all subsequent REPL input to come from that source. (It's okay to run inside DrRacket, however, even in the DrRacket REPL.)

Related

How to redefine a standard function within a scope in Racket?

I would like to redefine a standard Racket function, namely display, within a lexical scope, as in this example:
(with-custom-display (display "hello"))
This should work even when the code within the scope of with-custom-display is from a different library or even racket/* packages.
Is this possible? If so, how to do it?
EDIT:
If not possible in general, at least for the case of display and other write functions... could I somehow transform every output by parameterizing on current-output-port then redirecting the transformed output to the original port?
While its not possible1 to globally replace arbitrary functions in Racket, you absolutely CAN change the standard out port that a Racket program uses (and by extension, functions like display). In fact, this is exactly what the readline collection in racket does, except for input ports rather than output ports.
Basically, all you need to do is parameterize current-output-port globally to be your special port. Since you want to ultimately write out to the original output port (but with colors), you can also grab the original output port before changing it to the new one. Your resulting code would look something like this:
#lang racket/base ;; init.rkt
(define orig-port (current-output-port))
(define new-output-port
.... uses orig-port ....)
(current-output-port new-ouput-port)
(replacing .... uses orig-port .... with the implementation of your new colored output port)
And now, any file that requires "init.rkt" will get color in its default output port.
(Note though that if you have multiple files that do this same sort of thing, you have to be careful to make sure that they don't happen in an unsafe order.)
You can also make your with-custom-display form as a simple language extension by doing:
#lang racket ;; custom-disp.rkt
(provide with-custom-display)
(require syntax/parse/define)
(define orig-port (current-output-port))
(define new-output-port
.... uses orig-port ....)
(define-simple-macro (with-custom-display body ...)
(parameterize ([current-output-port new-output-port])
body ...))
This is the general idea of how DrRacket is able to print output to a DrRacket specific repl, rather than your consoles stdout.
1Normally anyway, there are usually ways to break things if you really want to. But that's almost always a bad idea. ;)

Call finish-output from format

I noticed that there is no
format directive which would
call force-output/finish-output.
Why?
It does seem to be useful in user interaction, cf.
Lisp format and force-output.
E.g., ~= could translate to finish-output, and ~:= to force-output.
I don't think clear-output makes much sense in this context, but we
might map ~#= to it for completeness.
PS. Cf. CLISP RFE.
Summary from comp.lang.lisp:
An explanation from Steven Haflich
The language defines no portable way to extend the set of format
directives (other then ~/.../) but that's not really the issue here.
The real problem is that it is not well defined to call finish-output or similar functions at arbitrary places during printing.
If pretty-printing is in progress, the stream received by a
pprint-dispatch or print-object method may be an encapsulating stream --
one that delays output temporarily until it can make decisions about
white space and line breaks. (There are also potential problems if
finish-output were called inside a ~< justification, but that directive
is a hairball!) What would one expect finish-output to do if called
inside a pretty print operation? I don't think it's well defined.
The problem isn't particular to format, of course, but a directive for
finish-output from format would just add another sharp edge to the
language. finish-output etc. are only safe to call when completely
outside an actual or implied call to cl:write. Call it as a function
at an appropriate point in your code (where you know execution isn't
inside a nested write) so the intention is clear and you don't mess up
printer internals.
A suggestion from Rob Warnock
Actually, no changes to format are needed. Just add this function somewhere in the COMMON-LISP-USER package:
(defun fo (stream arg colon-p atsign-p &rest params)
(declare (ignore arg params))
(cond
(colon-p (force-output stream))
(atsign-p (clear-output stream))
(t (finish-output stream))))
Then:
(progn
(format t "enter var: ~/fo/" nil)
(read))
enter var: 456
456
The problems with this (portable!) approach are
verbosity (~/fo/ instead of ~=)
need to consume a format argument (nil in the example above)

Change program code while running in Chicken Scheme

Is it possible to update the program code while it is being interpreted by csi, the Chicken Scheme Interpreter? If so, how?
So that I can interactively change part of the code and immediately see the effects of that changes.
For example, suppose I have written the following program:
(define (loop)
(print "Ciao")
(rest 1)
(loop))
(loop)
(assume (rest 1) has the effect of pausing the program for a second).
If I run this program, trough csi, it prints the string "Ciao" every second. If I change the string "Ciao" into something else, for example into "else", and I save the program code file, then csi continue interpreting the old program code, so I continuously see the string "Ciao". I'd like, in this case, that when I save the modified code with the string "Ciao" replaced by "else", csi continue its interpretation job by looking into the modified file, instead of the old file.
So that I obtain as output some "Ciao" followed by some "else": the "else" start to appear when I replace "Ciao" by "else" in the source code.
In general, the answer is "don't". The way you're supposed to use the REPL is by evaluating piecemeal changes against it, then evaluating a function or two to make sure everything went as expected. Part of this approach is structuring your program so that it can be easily tested in pieces, which implies not automatically starting any infinite loops. In the specific case you're asking about, you could instead write
(define (do-stuff)
(print "Ciao"))
(define (main-loop)
(do-stuff)
(rest 1)
(main-loop))
(define (start) (main-loop))
You can now incrementally develop do-stuff, periodically evaluating new versions to your interpreter and calling them to make sure they work, then eventually calling start once you're confident that it's doing the right thing.
You may get mileage out of this similar question asked about Common Lisp.
As an aside, if you were using Common Lisp and SLIME, you could now do more or less what you proposed:
(defun do-stuff ()
(format t "Ciao~%"))
(defun main-loop ()
(loop (progn (do-stuff)
(sleep 1))))
(main-loop)
Starting that up would start printing Ciao on separate lines in your SLIME REPL. If you changed do-stuff to
(defun do-stuff ()
(format t "else~%"))
then hit it with C-c C-c (the default binding for slime-compile-defun), you'd see your SLIME REPL start printing else lines in-flight.
CL-USER> (main-loop)
Ciao
Ciao
Ciao
; compiling (DEFUN DO-STUFF ...)else
else
else
else
else
else
; Evaluation aborted on NIL. User break.
CL-USER>
I'm not sure how to accomplish the same thing in Scheme, but I'm reasonably sure it's possible.
All that being said, you sometimes want to run a program part of which is an infinite loop. A real world example would be while testing a TCP server of some sort. If you're in such a situation, and your desired workflow is
Write file
Run csi my-file.scm
Edit file
Kill csi
Run csi my-file.scm
goto 3
and you basically just want to automate steps 4 through 6, you'll need an external tool to do it for you. Take a look at entr or hsandbox (the latter doesn't have Scheme support out of the box, but it doesn't look like it would be too hard to add).
There is no common way to make a running program check its source for changes but you there seems to be enough feratures available in Chicken to roll your own:
(use posix)
(use srfi-18)
(define (watch-reload! file)
(define (tsleep n)
(thread-sleep! (seconds->time (+ n (time->seconds (current-time))))))
(define (get-time)
(file-modification-time file))
(thread-start!
(lambda ()
(let loop ((filetime '()))
(let ((newtime (get-time)))
(when (not (equal? filetime newtime))
(load file))
(tsleep 10)
(loop newtime))))))
Now all you have to do is to use watch-reload! instead of load and it will check and reload every 10 seconds if the file has been modified.
If you save when the file is not valid scheme it stops working until you call watch-reload! on it again.
It may be that chicken programmers might have a better solution.

Equivalent of python 'pass' in drracket

Does anyone know if DrRacket has got an equivalent of Python's pass statement or any other idiom that can be used to instruct the executing code to do nothing?
If you want to write an empty statement (one with no useful result), maybe this will work for you:
(void)
... But it'd be better if you demonstrated with an example what exactly is that you want to do. Anyway, here's a link to the appropriate section in the documentation.
Here is a way to do your hash example.
(hash-ref (hash) "not there" void)
But now you have to check whether you get back a void or a value you want. You may also be interested in hash-update! or hash-update (docs), which combines checking for an existing key with a default behavior for the case where the key does not exist.
As I write this answer, your question is kind of spread among (a) your original question and (b) your comment to Oscar's answer:
Its a case of wanting to indexing a hash map with a key that may or may not exist so if a no key found error returns, I just want to ignore the error and continue with the execution.
Taking that last part literally: The general way to handle -- and effectively "ignore" -- an exception is with-handlers:
(hash-ref (hash) "nothing")
;; hash-ref: no value found for key
;; key: "nothing"
(with-handlers ([exn:fail? (lambda (exn)
"hum dee dum")])
(hash-ref (hash) "nothing"))
;; "hum dee dum"
This doesn't seem to have anything to do with Python pass as described here, but maybe pass can be used to ignore errors in Python; I just don't know it well enough
If you can deal with a syntactic form, then begin works.
(if <conditional> (begin))
if you need a function then this works
(lambda ignore #f)
And you might just avoid the need for 'something that does nothing' by reworking your logic leading to the 'nothing'.

How to trace a program for debugging in OCaml ?

I have a general question regarding coding practices...
While debugging, at some point of my code, I need some code to print the current state; When I don't debug, I don't want to leave the code there because it bothers visibility of other code...
It is hard to package them into one function because most of the time, it involves local variables, and I don't want to pass everything as arguments...
So how do you generally manage this kind of "printing/checking" code? is there any good practice?
I used to have a debug function, that would only print the final string only if a flag was set. Now, I prefer to just add if statements:
they are not much longer
nothing is computed is the condition is false
it is easy while reading the code to see that it is only for debugging
I also used to have camlp4 macros, that would generate if statements from function applications, but it only works in projects where camlp4 is used, which I tend to avoid nowadays.
Note that, usually, I use not one debug flag, but many debug flags, one per module, and then meta-tags that will trigger debugging of several modules or orthogonal aspects. They are put in a hashtable as list of flags, and I can set them with either an argument or an environment variable.
I often use a debug function which prints value only when a debug flag is set to true:
let debug_flag = ref false
let debug fmt =
if !debug_flag then Printf.eprintf fmt
else Printf.ifprintf stderr fmt
I use a logging syntax extension:
http://toss.svn.sourceforge.net/viewvc/toss/trunk/Toss/caml_extensions/pa_log.ml?revision=1679&view=markup
You can also pass line number to the logging function (which is hard-coded to AuxIO.log in the source above) using Loc.start_line _loc (perhaps I'll add it).
Note that the conditional should be part of the syntax extension, this way it will not compute the arguments if it does not need to print them. Also, we have the flexible "printf" syntax.
Also, I use a command in Emacs:
(defun camldev-insert-log-entry ()
(interactive)
(insert "(* {{{ log entry *)
LOG 2 \"\";
(* }}} *)")
(goto-char (- (point) 12)))
together with `folding-mode'.

Resources