Sync/choice-evt over multiple channels (number determined at runtime) - racket

I am trying to create a very simple program, intended to measure the time required to select and synchronise across multiple channels. Essentially, the concept is simply that I have one sender and one receiver. Throughout multiple iterations, the sender randomly selects one of the channels the two have been provided and sends a message on that channel. As part of this, I need to be able to control the number of channels involved as a command-line parameter to the program, so I can't hard-code a pre-determined number of channels into the program. The problem is, I can't figure out how to get either sync or choice-evt from the Synchronisation module to work with multiple channels.
The entire program (as I currently have it) is below:
#lang racket
(provide main)
(require racket/random)
(define (sender iterations channels)
(match iterations
[0 (displayln "sender completed")]
[iter
(let ([choice-chan (random-ref channels)])
(channel-put choice-chan iter)
(sender (- iter 1) channels))]))
(define (receiver iterations channels notification-semaphore)
(match iterations
[0 (begin
(displayln "receiver completed")
(semaphore-post notification-semaphore))]
[iter
(let ([ignored-choice (sync (choice-evt (vector->values channels)))])
(begin (displayln ignored-choice)
(receiver (- iter 1) channels notification-semaphore)))]))
(define (experiment iterations num-channels)
(let ([channels
(vector->immutable-vector
(build-vector num-channels (λ (i) (make-channel))))]
[notification-semaphore (make-semaphore)])
(thread (λ () (receiver iterations channels notification-semaphore)))
(thread (λ () (sender iterations channels)))
(semaphore-wait notification-semaphore)))
(define (main iterations num-channels)
(experiment (string->number iterations) (string->number num-channels))
(displayln "SelectTime completed successfully"))
The displayln expressions aren't strictly necessary, they're just there so that I can see that there is indeed something being passed from sender to receiver.
The issue I have is that, when I use only a single channel, everything seems to work fine. With two or more channels, however, I get a runtime error complaining about an arity mismatch - 1 value was expected but 2 (or more if I specified more on the command line) were provided. Best as I can tell, this error occurs inside the receiver function at the evaluation of (choice-evt (vector->values channels)), after processing the inner expression. I have tried every variation I can think of, such as using channels directly without the vector->values; changing the vector to a list; dropping the choice-evt (especially since, if I'm reading the docs right, that isn't actually necessary for my test); moving where the sync happens out of the variable declaration in the let.
How can I sync over multiple channels, when the number of channels won't be known at runtime? It looks like using a vector or list isn't the correct way to go about this, but I'm a bit stumped as to what is the correct way.
P.S. Please do feel free to critique the program in other ways while you're answering if you think that might be helpful :)

You can use apply to make a choice-evt from a variable-length list of channels. For example, in your code above, change the sync call to the following:
(sync (apply choice-evt (vector->list channels)))

Related

Find max in lisp

I am trying to do Recursive method to find max value in list.
Can anyone explain where I made the mistake on this code and how to approach it next time.
(defun f3 (i)
(setq x (cond (> (car (I)) (cdr (car (I))))
(f3 (cdr (I)))))
)
(f3 '(33 11 44 2) )
also I tried this following method and didn't work:
(defun f3 (i)
(cond ((null I )nil )
(setq x (car (i))
(f3(cdr (i)))
(return-from max x)
)
Thanks a lot for any help. I am coming from java if that helps.
If you're working in Common Lisp, then you do this:
(defun max-item (list)
(loop for item in list
maximizing item))
That's it. The maximizing item clause of loop determines the highest item value seen, and implicitly establishes that as the result value of loop when it terminates.
Note that if list is empty, then this returns nil. If you want some other behavior, you have to work that in:
(if list
(loop for item in list
maximizing item))
(... handle empty here ...))
If the number of elements in the list is known to be small, below your Lisp implementation's limit on the number of arguments that can be passed to a function, you can simply apply the list to the max function:
(defun max-item (list)
(apply #'max list))
If list is empty, then max is misused: it requires one or more arguments. An error condition will likely be signaled. If that doesn't work in your situation, you need to add code to supply the desired behavior.
If the list is expected to be large, so that this approach is to be avoided, you can use reduce, treating max as a binary function:
(defun max-item (list)
(reduce #'max list))
Same remarks regarding empty list. These expressions are so small, many programmers will avoid writing a function and just use them directly.
Regarding recursion, you wouldn't use recursion to solve this problem in production code, only as a homework exercise for learning about recursion.
You are trying to compute the maximum value of a list, so please name your function maximum and your parameter list, not f3 or i. You can't name the function max without having to consider how to avoid shadowing the standard max function, so it is best for now to ignore package issues and use a different name.
There is a corner case to consider when the list is empty, as there is no meaningful value to return. You have to decide if you return nil or signal an error, for example.
The skeleton is thus:
(defun maximum (list)
(if (null list)
...
...))
Notice how closing parentheses are never preceded by spaces (or newlines), and opening parentheses are never followed by spaces (or newlines). Please note also that indentation increases with the current depth . This is the basic rules for Lisp formatting, please try following them for other developers.
(setq x <value>)
You are assigning an unknown place x, you should instead bind a fresh variable if you want to have a temporary variable, something like:
(let ((x <value>))
<body>)
With the above expression, x is bound to <value> inside <body> (one or more expressions), and only there.
(car (i))
Unlike in Java, parentheses are not used to group expressions for readability or to force some evaluation order, in Lisp they enclose compound forms. Here above, in a normal evaluation context (not a macro or binding), (i) means call function i, and this function is unrelated to your local variable i (just like in Java, where you can write int f = f(2) with f denoting both a variable and a method).
If you want to take the car of i, write (car i).
You seem to be using cond as some kind of if:
(cond (<test> <then>) <else>) ;; WRONG
You can have an if as follows:
(if <test> <then> <else>)
For example:
(if (> u v) u v) ;; evaluates to either `u` or `v`, whichever is greater
The cond syntax is a bit more complex but you don't need it yet.
You cannot return-from a block that was undeclared, you probably renamed the function to f3 without renaming that part, or copied that from somewhere else, but in any case return-from is only needed when you have a bigger function and probably a lot more side-effects. Here the computation can be written in a more functionnal way. There is an implicit return in Lisp-like languages, unlike Java, for example below the last (but also single) expression in add evaluates to the function's return value:
(defun add-3 (x)
(+ x 3))
Start with smaller examples and test often, fix any error the compiler or interpreter prints before trying to do more complex things. Also, have a look at the available online resources to learn more about the language: https://common-lisp.net/documentation
Although the other answers are right: you definitely need to learn more CL syntax and you probably would not solve this problem recursively in idiomatic CL (whatever 'idiomatic CL' is), here's how to actually do it, because thinking about how to solve these problems recursively is useful.
First of all let's write a function max/2 which returns the maximum of two numbers. This is pretty easy:
(defun max/2 (a b)
(if (> a b) a b))
Now the trick is this: assume you have some idea of what the maximum of a list of numbers is: call this guess m. Then:
if the list is empty, the maximum is m;
otherwise the list has a first element, so pick a new m which is the maximum of the first element of the list and the current m, and recurse on the rest of the list.
So, we can write this function, which I'll call max/carrying (because it 'carries' the m):
(defun max/carrying (m list)
(if (null list)
m
(max/carrying (max/2 (first list) m)
(rest list))))
And this is now almost all we need. The trick is then to write a little shim around max/carrying which bootstraps it:
to compute the maximum of a list:
if the list is empty it has no maximum, and this is an error;
otherwise the result is max/carrying of the first element of the list and the rest of the list.
I won't write that, but it's pretty easy (to signal an error, the function you want is error).

Lazy reads of custom types in Racket

I'm new to Racket, and I am trying to write a function to read the lines of a file, parse each line into a struct, and return a lazy sequence of my data type. Here is a simple example of my input format (a matrix with row and column names). My actual input format also includes a header line, which I am omitting here, and consists of very large files, which is why I need the laziness.
R1 1.0 2.3 1.2
R2 1.2 3.1 3.4
Here is my latest attempt:
(struct row (key data))
(define (read-matrix in)
(for [(line (in-lines in))]
(let ([fields (string-split line "\t")]
(row (first fields) (list->vector (map string->number (rest fields))))
)))
I have also tried numerous other approaches including using call-with-input-file. My problem with the approach above is that if I use #lang racket it isn't lazy, and with #lang lazy string-split isn't defined. I should add that in my use case, the semantics I want is to close the port when the entire sequence has been consumed, because I can guarantee that either the whole sequence will be consumed, or the program will terminate.
So, am I on the right track? What approach should I take to solve this problem? Thanks!
I was composing this answer off-line, and came back to find you'd mostly answered it already. I'll post anyway in case the details are helpful to anyone.
If you really need #lang lazy, and want to use string-split, I think you can simply (require racket/string) to use it?
I'm not sure I understand exactly what you mean by "lazy", here. Using in-lines will not suck the entire file into memory, if that's your concern. It will process things one line at a time.
One thing you could do is define a helper function, that handles reading and parsing the line, checking for eof, and closing the input port automatically:
(struct row (key data)
#:transparent)
;; Example couple lines of input to use below.
(define text "R1 1.0 2.3 1.2\nR2 1.2 3.1 3.4")
;; read-matrix-row : input-port? -> (or/c eof row?)
;;
;; Given an input port, try to read another row.
(define (read-matrix-row in)
(match (read-line in)
[(? eof-object?)
(close-input-port in)
eof]
[line (match (string-split line " ")
[(cons key data)
(row key (list->vector (map string->number data)))])]))
You could use this function in a number of ways. One way is with in-producer:
;; Example use with in-producer:
(let ([in (open-input-string text)])
(for/list ([x (in-producer read-matrix-row eof in)])
x))
;; => (list (row "R1" '#(1.0 2.3 1.2))
;; (row "R2" '#(1.2 3.1 3.4)))
That example uses for/list to make list. Of course if you have a giant input file, that will yield a giant list. But you could display them one by one, or write them one by one to a file or database:
;; Example use, displaying one by one.
(let ([in (open-input-string text)])
(for ([x (in-producer read-matrix-row eof in)])
(displayln x))) ;or write to some file, for example
If instead you prefer a stream interface, it's easy to create a stream from any sequence including `in-producer':
;; If you prefer a stream interface, we can use sequence->stream to
;; transform the producer sequence into a stream:
(define (matrix-row-stream in)
(sequence->stream (in-producer read-matrix-row eof in)))
;; Example interactive use of the stream
(define stm (matrix-row-stream (open-input-string text)))
(stream-empty? stm) ;#f
(stream-first stm) ;(row "R1" '#(1.0 2.3 1.2))
(stream-empty? (stream-rest stm)) ;#f
(stream-first (stream-rest stm)) ;(row "R2" '#(1.2 3.1 3.4))
(stream-empty? (stream-rest (stream-rest stm))) ;#t
Try using the functions from SRFI-13, which is a string manipulating library also available in #lang lazy:
(require srfi/13)
And then do this:
[fields (string-tokenize line)]
Ultimately I found that the answer was to use Racket's sequence, streams, and generator libraries for this kind of thing. The generators are especially nice, allowing a simple Python-like "yield" function. These features allow lazy sequences without full-on lazy evaluation as provided by #lang lazy.
http://docs.racket-lang.org/reference/streams.html

How do I do anything with multiple return values in racket?

It seems like in order to use multiple return values in Racket, I have to either use define-values or collect them into a list with (call-with-values (thunk (values-expr)) list). In the latter case, why would someone to choose to return multiple values instead of a list, if just have to collect them into a list anyway? Additionally, both of these are very wordy and awkward to work into most code. I feel like I must be misunderstanding something very basic about multiple-return-values. For that matter, how do I write a procedure accepting multiple return values?
Although I may be missing some of the Scheme history and other nuances, I'll give you my practical answer.
First, one rule of thumb is if you need to return more than 2 or 3 values, don't use multiple values and don't use a list. Use a struct. That will usually be easier to read and maintain.
Racket's match forms make it much easier to destructure a list return value -- as easy as define-values:
(define (f)
(list 1 2))
(match-define (list a b) (f))
(do-something-with a b)
;; or
(match (f)
[(list a b) (do-something-with a b)])
If you have some other function, g, that takes a (list/c a b), and you want to compose it with f, it's simpler if f returns a list. It's also simpler if both use a two-element struct. Whereas call-with-values is kind of an awkward hot mess, I think.
Allowing multiple return value is an elegant idea, because it makes return values symmetric with arguments. Using multiple values is also faster than lists or structs (in the current implementation of Racket, although it could work otherwise).
However when readability is a higher priority than performance, then in modern Racket it can be more practical to use a list or a struct, IMHO. Having said that I do use multiple values for one-off private helper functions.
Finally, there's a long, interesting discussion on the Racket mailing list.
Racket doc gives us the quintessential example why, in disguise:
> (let-values ([(q r) (quotient/remainder 10 3)])
(if (zero? r)
q
"3 does *not* divide 10 evenly"))
"3 does *not* divide 10 evenly"
We get two values directly, and use them separately in a computation that follows.
update: In Common Lisp, with its decidedly practical, down-to-the-metal, non-functional approach (where they concern themselves with each extra cons cell allocation), it makes much more sense, especially as it allows one to call such procedures in a "normal" way as well, automatically ignoring the "extra" results, kind of like
(let ([q (quotient/remainder 10 3)])
(list q))
But in Racket this is invalid code. So yeah, it looks like an extraneous feature, better to be avoided altogether.
Using list as the consumer defeats the purpose of multiple values so in that case you could just have used lists to begin with. Multiple values is actually a way of optimization.
Semanticly returning a list and several values are similar, but where you return many values in a list effort goes into creation of cons cells to make the list and destructuring accessors to get the values at the other end. In many cases however, you wouldn't notice the difference in performance.
With multiple values the values are on the stack and (call-with-values (lambda () ... (values x y z)) (lambda (x y z) ...) only checks the number to see if it's correct.. If it's ok you just apply the next procedure since the stack has it's arguments all set from the previous call.
You can make syntactic sugar around this and some popular ones are let-values and SRFI-8 receive is a slightly simpler one. Both uses call-with-values as primitive.
values is handy because it
checks that the number of elements returned is correct
destructures
For example, using
(define (out a b) (printf "a=~a b=~a\n" a b))
then
(let ((lst (list 1 2 3)))
(let ((a (first lst)) (b (second lst))) ; destructure
(out a b)))
will work even though lst has 3 elements, but
(let-values (((a b) (values 1 2 3)))
(out a b))
will not.
If you want the same control and destructuring with a list, you can however use match:
(let ((lst (list 1 2)))
(match lst ((list a b) (out a b))))
Note that he creation of the structure, e.g. (list 1 2) vs (values 1 2) is equivalent.

What is "3D syntax"?

In the context of writing Racket macros, what does "3D syntax" mean?
I've heard the phrase a few times. Including once in reference to a macro I was writing. But that was awhile ago; I fixed it, and now I can't remember exactly what I was doing wrong originally.
Also: Is 3D syntax always bad? Or is it like eval (where if you think you need to use it, you're probably wrong, but there are some valid uses in expert hands)?
Syntax objects are usually supposed to be just serializable data. 3D-syntax weakens this condition: it allows us to sneak in arbitrary values, and not just plain data. That's what makes them "3d": they are values that rise above the regular flat things you'd expect out of syntax objects.
For example, we can sneak in lambda values!
#lang racket
(define ns (make-base-namespace))
(define (set-next! n)
(parameterize ([current-namespace ns])
(eval #`(define next #,n)))) ;; <-- 3d-syntax here
(define (compute s)
(parameterize ([current-namespace ns])
(eval s)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define counter 0)
(set-next! (lambda ()
(set! counter (add1 counter))
counter))
(compute '(+ (next)
(next)
(next)
(next)))
Doing this is usually a bad thing, because the presence of such values probably means an ill-founded attempt to leak information across phases of compilation. The result is something that's likely not separately-compilable. If you see an error that sounds something like:
write: cannot marshal value that is embedded in compiled code value
then that is most likely due to a macro having produced a piece of 3d-syntax that can't be serialized to bytecode.
Sometimes, in rare situations, we really do want 3d-syntax, often in dynamic evaluation contexts. As a concrete example, a debugger in DrRacket may want to annotate the syntax of a program so that function applications directly call back into functions of the debugger, so that we can do things like interactive code coverage coloring in the program editor. In that sense, 3d-syntax can act as a communication channel between dynamically-evaluated code and its ambient environment.

Standard way for breaking out of recursion in scheme

I am writing my first program in scheme. I get pretty deep into recursion because I basically interpret a program for a simple robot which can have nested procedure calls.
If I find a violation I need to stop interpreting the program and return the last valid state.
I've solved it by declaring a global variable (define illegalMoveFlag 0) and then setting it via set!.
It works fine, but I guess my tutor won't like it (because it's not functional approach I guess)
Other approach I've thought about is to add an error parameter to every function I call recursively in the program. I don't quite like it because it would make my code far less readable, but I guess it's more 'functional'.
Is there maybe a third way I didn't think about? And can my approach be justified in this paradigm, or is it basically a code smell?
Since this was your first Scheme program, you probably just need to introduce a conditional expression, cond, in order to avoid further recursion when you reach the end. For example:
; sum : natural -> natural
; compute the sum 0+1+...+max
(define (sum max)
(define (sum-helper i sum-so-far)
(if (> i max)
sum-so-far
(sum-helper (+ i 1) (+ sum-so-far i))))
(sum-helper 0 0))
(display (sum 10))
(newline)
However, if you need a traditional return to return like longjmp in C, you will need to store and use an escape continuation. This can be done like this:
(define (example)
(let/ec return
(define (loop n)
(if (= n 100000)
(return (list "final count: " n))
(loop (+ n 1))))
(loop 0)))
(display (example))
If let/ec is not defined in your Scheme implementation, then prefix your program with:
(define-syntax let/ec
(syntax-rules ()
[(_ return body ...)
(call-with-current-continuation
(lambda (return)
body ...))]))
UPDATE:
Note that cond has an => variant:
(cond
[(call-that-can-fail)
=> (lambda (a) <use-a-here>))]
[else <do-something-else>])
If the call succeeds then the first, clause is
taken and the result is bound to a. If the call fails,
then the else clause is used.
The usual way to stop recursing is, well, to stop recursing. i.e., don't call the recursive function any longer. :-)
If that is too hard to do, the other way to break out of something is to capture a continuation at the top level (before you start recursing), then invoke the continuation when you need to "escape". Your instructor may not like this approach, though. ;-)
You might want to use the built-in procedure error, like so:
(error "Illegal move") ; gives ** Error: Illegal move
This will raise an exception and stop interpreting the program (though I suspect this may not be what you are looking for).
You can also provide additional arguments, like this:
(error "Illegal move: " move) ; gives ** Error: Illegal move: <move>
You can exit of a recursion (or from any other process) using a continuation. Without knowing more specifics, I'd recommend you take a look at the documentation of your interpreter.
Make illegalMoveFlag a paramter in the function instead of a global variable
I'll give you a simple example with factorials
ie:
0! = 1
n! = n * (n - 1)! when n (1 ... infinity)
lets call this a recursive factorial
(define (fact-r n)
(if
[eq? n 0]
1
(* n (fact-r (- n 1)))
)
)
An alternative would be to use a parameter to the function to end the recursion
Lets call it iterative factorial
(define (fact-i n total)
(if
(eq? n 0)
total
(fact-i (- n 1) (* n total))
)
)
total needs to start at 1 so we should make another function to make using it nicer
(define (nice-fact n)
(fact-i n 1))
You could do something similar with illegalMoveFlag to avoid having a global variable
As far as avoiding using set! goes, we'll probably need more information.
In some cases its still rather hard to avoid using it. Scheme is fully turing complete without the use of set! however when it comes to accessing an external source of information such as a database or a robot set! can become the only practical solution...