Randomly sampling an item always returns the same value - random

I am attempting to write a script that samples one of my colleagues' names randomly:
#!/usr/bin/env gosh -b
(define-module utils
(use data.random :only (samples$ integers-between$))
(use gauche.generator :only (generator->list))
(export generator->first
sample1)
(define (generator->first gen)
(car (generator->list gen 1)))
(define (sample1 items)
(generator->first (samples$ items))))
(import (utils :only (sample1)))
(define team-members
(list "billy"
"nilly"
"silly"
"willy"))
(define (main args)
(print (sample1 team-members))
0)
However it always emits the same value:
for i in {1..25}; do
gosh ./random-team-member
done
Why is this happening?
Do I need to somehow initialize the random number generator? Am I misusing generator->list?

Observe the documentation for data.random.
The random seed is initialized by a fixed value when the module is loaded. You can get and set the random seed [with random-data-seed].
I don't see any obvious way to initialize the random seed from some other source of randomness, such as the system clock. So if you want unpredictable randomness, you'll need to find entropy yourself - perhaps read from /dev/urandom?

Related

miniKanren: How to define #s and #u?

In miniKanren, succeed can be defined as (define succeed (== #t #t)), and fail can be defined as (define fail (=== #t #f)). But what about #s and #u as short forms of succeed and fail, as they appear in The Reasoned Schemer?
(define #s succeed) produces an error in Racket:
Welcome to Racket v7.2.
> (require Racket-miniKanren/miniKanren/mk)
> (define #s succeed)
; readline-input:2:8: read-syntax: expected `(`, `[`, or `{` after `#s` [,bt
; for context]
#<procedure:...iniKanren/mk.rkt:337:4>
; readline-input:2:18: read-syntax: unexpected `)` [,bt for context]
I have the feeling that this has something to do with reader macros.
How can I define #s for succeed and #u for fail in Scheme and also in Racket?
I am using the canonical miniKanren implementation for Scheme and the canonical miniKanren implementation for Racket.
Identifiers in Racket can not begin with #. It is simple to bind the identifiers s and u. Redefining the meaning of #s and #u is not as simple, since it needs to happen in the reader. Normally #something signals to reader that something special is to be read.
The input (foo bar) will be read as a list, #(foo bar) will be read as a vector, and #s(foo bar) will be read as a structure. You can read about the standard syntax here:
https://docs.racket-lang.org/reference/reader.html?q=%23s#%28mod-path._reader%29
Now if you want to change the meaning of #s and #u you need to look at readtables.
Each time the reader sees an # it consults a readtable to see how to handle the following characters. Since reading happens before parsing/expansion and evaluation, you can't change the reader simply by calling a function in your program. You will need to either use
the #reader extension mechanism or create your own language.
For more on readtables: https://docs.racket-lang.org/reference/readtables.html?q=reader-macro
The Guide has an example of how to use reader extensions:
https://docs.racket-lang.org/guide/hash-reader.html
I solved all the book using
(define succeed
(lambda (s)
`(,s)))
(define SUCC succeed)
(define fail
(lambda (s)
'()))
On the other side, you should consult the source code provided by Friedman & Byrd. I solved it using mit-scheme -- no specific feature of racket is used, R6RS is enough.
For Racket, #s and #u can be defined as such (reference: Using Racket for The Reasoned Schemer):
;; #s for succeed.
(current-readtable
(make-readtable (current-readtable)
#\s
'dispatch-macro
(lambda (ch port src line col pos) succeed)))
;; #u for fail.
(current-readtable
(make-readtable (current-readtable)
#\u
'dispatch-macro
(lambda (ch port src line col pos) fail)))
Note that this only works in the REPL.
This defines #s and #u by modifying the readtable.
For Scheme, adding read syntax is defined in SRFI-10 sharp-comma external form, but the resulting #,() forms are probably awkward for most tastes. For Scheme, it is best to just define s and u because there is currently no portable way to define #s and #u.

Completion for frame local variables from backtrace

I'm trying to add completion at point for frame-local variables from backtrace-frames during invocations of read--expression by debugger-eval-expression or edebug-eval-expression.
I constructed the following completion table to add frame-local variables to the already available table for local elisp variables,
;; completion table for locals in current frame
(defvar my-backtrace-locals-completion-table
(completion-table-in-turn
(completion-table-dynamic
(lambda (_string)
(when-let* ((idx (backtrace-get-index)) ;backtrace.el
(frame (nth idx backtrace-frames)))
(backtrace-frame-locals frame)))
'do-switch-buffer)
elisp--local-variables-completion-table)) ;elisp-mode.el
which seems to work fine, eg. to reproduce
(1) evaluate
;; debug-on-error = t
(let ((my-local-var '(1 2))) (mapcan #'car this-local-var))
(2) from debugger's second frame, evaluate with eval-expression
(funcall my-backtrace-locals-completion-table "my-" nil t)
returns expected ("my-local-var").
The problem is following the above steps, but calling instead calling debugger-eval-expression doesn't work. The environment where the table is evaluated isn't finding a backtrace-frame (with or without do-switch-buffer).
How can I define the table to be evaluated in the proper buffer?
emacs v27.0.50
The completion table above doesn't quite return the expected candidates for debugger-eval-expression. The environment where the expression is evaluated has locals from frames higher than, but not including, the one at point in the Backtrace buffer.
So, the available locals should be only those from higher frames, eg.
(eval-when-compile (require 'dash))
(defvar my-backtrace-locals-completion-table
(completion-table-dynamic
(lambda (_string)
(when backtrace-frames
(--mapcat
(-some->> (backtrace-frame-locals it) (--map (car it)))
(nthcdr (1+ (backtrace-get-index)) backtrace-frames))))
'do-switch-buffer))
Then, redefining debugger-eval-expression's interactive spec to use the new locals table in place of the normal elisp table provides the correct completions (passing the 'do-switch-buffer arg completion-table-dynamic to find completions in the original buffer).
(defun my-backtrace#eval (orig-fn exp &optional nframe)
(interactive
(let ((elisp--local-variables-completion-table
my-backtrace-locals-completion-table))
(list (read--expression "[my] Eval in stack frame: "))))
(apply orig-fn (list exp nframe)))
(advice-add 'debugger-eval-expression :around #'my-backtrace#eval)

Racket: What does it mean to bind names to the index?

I'm writing code where the user picks from a list of choices. I have defined my list in the following:
;contains the options the user can pick
(define choices (list "choice1" "choice2" "choice3" "choice4" "choice5" "choice6" "OPENING VALUE" "HIGHEST VALUE" "LOWEST VALUE" "CLOSING VALUE" "VOLUME OF SHARES" "ADJUSTED CLOSING VALUE"))
My button gets the name from the list from the following code(only showing one example). In this case it takes the third item from the list:
[label (list-ref choices 2)]
and when I want to change the name then I use the line of code:
(send choice-4-9 set-label (list-ref choices 9))
My prof commented that I should bind names to 6 7 etc so your code would be readable. I'm still a little confused on what he meant by that and how I would do so.
He means for each index, define an identifier bound to that index, ideally named after what it means, e.g.:
(define choice1 0)
(define choice2 1)
(define choice3 2)
....
So now you can write [label (list-ref choices choice3)] instead of [label (list-ref choices 2)]. The code is more readable, and easier to change if necessary because you can change the binding of the identifier rather than every place where the number appears in code.
Incidentally, what you're doing now is called using "magic numbers."
The previous answer is good and I have upvoted it. I only want to mention that a common data structure for something like this is an association list, where you associate something like a symbol or number to a value, and then look it up using assq, assv, or assoc depending on the whether your lookup name requires eq?, eqv?, or equal? respectively. Consider:
(define choices
'((shoot . "Shoot!")
(run . "Run away!")
(reload . "Reload")
(appraise . "Search your surroundings")))
(define (get-label choice)
(let ((result (assq choice choices)))
(if (not result)
(error "???") ; handle as you see fit
(cdr result))))
;;;;;;;;;;;;;;;;
Welcome to DrRacket, version 6.4 [3m].
Language: racket/base [custom]; memory limit: 8192 MB.
> (get-label 'shoot)
"Shoot!"
>

Temporary Variable Assistance (Scheme)

I'm making a random sentence generator using Scheme (Pretty Big), and I'm having trouble defining temporary variables. I want to make something like this:
<NOUN1> <VERB1> <NOUN2> <but> <NOUN2> <VERB1> <NOUN2> <also>
Example: Sharks eat fish, but fish eat fish also.
I have word lists, and functions to choose a word from said list. Then, I use append to create a function. I am able to do:
(define (sentence)
(append (getNoun) '(and) (getNoun) (getVerb)))
However, I am unable to figure out a way to temporarily define a variable.
I have this so far:
(define (sentence1)
(append (getNoun)
(lambda (verb getVerb)
(noun getNoun))
(verb) (noun) '(but) (noun) (verb) (noun)))
Hints/Help please?
You are looking for let.
http://docs.racket-lang.org/reference/let.html
Here is an example usage:
(define (my-proc age)
(let ([age-plus-10 (+ age 10)])
(printf "age is ~a" age)
(printf "age-plus-10 is ~a" age-plus-10)))
Notice how we can temporarily define age-plus-10 and then use it later.

How to inspect/export/serialize a (guile) Scheme environment

I'd like to export or replicate a scheme environment in another guile process. The algorithm I'm imagining would do something like this to serialize:
(map (lambda (var val) (display (quasiquote (define ,var ,val))
(newline))
(get-current-environment))
And then I'd read/eval that on the other end.
However, while there are functions that return the current environment, they are in some internal format that I can't just map across. How can I "walk" the environment as the above? Alternatively, how else can I replicate an environment into another process?
you may decompose the so-called "current-environment" like this:
(define (get-current-binding-list)
(let* ((e (current-module)) ;; assume checking current-module
(h (struct-ref e 0)) ;; index 0 is current vars hashtable
)
(hash-map->list cons h) ;; return a vars binding list
))
and you can call (get-current-binding-list) to get variables binding list in current-module.
Please note that each element in this list is a pair of symbol and variable type, say, (symbol-name . variable-type). So you may print it like this:
for a instance ,you got a var binding:
(define abc 5)
then:
(let ((vl (get-current-binding-list)))
(assoc-ref vl 'abc)
)
==> #<variable 9bb5108 value: 5>
This result is a "variable type" of variable "abc". You can get it's value with variable-ref procedure.
So you can trace all the bindings and do something ,in your code ,it's simply print var-name and var-value.
I know my answer is too brief, but I think there's enough information to help you to find more details in the manual.
Hope this will help you.
You can't really serialize Scheme environment. I don't known even it's possible to (portably) serialize continuations. Oh, and don't forget about FFIs. Ports and threads are unserializable too.

Resources