Append two mutable lists - racket

I want to write append!.
For example: if I have
(define ml1 (mlist 1 2 3))
(define ml2 (mlist 4 5 6))
ml1
ml2
'#&(#&1 . #&(#&2 . #&(#&3 . #&())))
'#&(#&4 . #&(#&5 . #&(#&6 . #&())))
I would like to be able to do this:
(append! ml1 ml2)
(mlist->list ml1)
;; produces '(1 2 3 4 5 6)

See the documentation on mappend!
(require racket/mpair)
(mappend! ml1 ml2)

The basic strategy will be to get to the end of the first list via repeated calls to mcdr, and then use set-mcdr! to set the last cons cell of the first list to the head of the second list.
For instance, using your definitions, this should work to append ml2 to ml1
(set-mcdr! (mcdr (mcdr ml1)) ml2)
(mlist->list m1) ; => '(1 2 3 4 5 6)
Now all you have to do is turn it into a function for arbitrary sized mlists and account for empty lists being passed in and what-not.

Related

Variable In- output in ACT-R Chunk

Given Unit1 standard ACTR documentary code:
(add-dm
(b ISA count-order first 1 second 2)
(c ISA count-order first 2 second 3)
(d ISA count-order first 3 second 4)
(e ISA count-order first 4 second 5)
(firstgoal ISA count-from start 0 end 5)
)
question:looking at the 0 and the 5 in den firstgoal chunk. Is it possible to declare that more generic like:
(firstgoal ISA count-from start *global_start_var* end *global_end_var*)
Is it possible to output a specific value in an chunk?
Speaking of the counter I want a code running the model and then evaluate the number which the counter model counted to
Example how a lisp code might look like with proper value infiltration in the lisp model
;; load the model
(load "counter.lisp")
;; set the start and end variables
(setvar *global_start_var* 0)
(setvar *global_start_end* 9)
;; run the model
(run 9999)
;; safe the result of the counter in the (local) variable result using the function get_val
(result (get_val))
To set the chunk contents using Lisp variables you can use the add-dm-fct function which takes a list of chunk description lists:
(add-dm-fct (list (list 'firstgoal 'ISA 'count-from 'start *global_start_var* 'end *global_end_var*)))
To get the current value from the slot of a chunk you need to use the macro chunk-slot-value or the function chunk-slot-value-fct. Those both take two parameters: the name of the chunk and the name of the slot, and then return the value of that slot in that chunk.
With the chunks you've shown there, this:
(chunk-slot-value b first)
will return 1.

Strange output after putting a "prime" on an identifier in Racket REPL

Today, I made a typing mistake in the REPL and discovered a strange behaviour. Here's a sample of the interaction:
Welcome to Racket v6.11.
> (define x 3)
> x
3
> x'
3
> x
'x
>
So the first x I typed resulted in 3, which is expected. The x' I accidentally typed resulted in 3, which is unexpected. The last x resulted in 'x (!!).
It seems like there is something I don't understand about how the REPL reads values. Could someone explain why the REPL behaves in this way?
See Racketrivia: Using ' as an "identifier suffix" on the racket mailing list. The reply by Robby Findler and the reply by Matthias Felleisen both explain this.
The first line, x, is normal.
The second line, x', is actually an "expression and-a-half." It's interpreted as an expression x followed by an unfinished expression '. The unfinished expression is allowed to be finished on the next line. Whatever you put on the next line will be put as the second half of ' next-line.
That means the third x is actually interpreted as the second half of ' x.
You can see a better example of unfinished expressions with parentheses:
> 1 (list 2 ; 1 followed by an unfinished expression
1
> 3 4) ; finishing it
'(2 3 4)
> 3 4) ; on its own without the `(list 2` before it it's an error
3
4
; readline-input:13:3: read-syntax: unexpected `)` [,bt for context]
The quote after an expression is interpreted in a similar way:
> 1 ' ; 1 followed by an unfinished expression
1
> (indefatigable inexhaustible) ; finishes previously unfinished, put after a quote
'(indefatigable inexhaustible)
> (indefatigable inexhaustible) ; on its own without the quote before it it's an error
; indefatigable: undefined;
; cannot reference an identifier before its definition
; in module: top-level
; internal name: indefatigable

Processing raw binary data with Racket

I am new to Racket Lang and previously I wrote thousands of lines of code in C++, Java and C. I am trying to figure out how to do the following task:
Given an array (like C uint8_t array) with the following format:
First byte is used to indicate the "format", let's say this could be 0x0a, 0x0b and so on.
Remaining data may include C strings without the null terminator and integers.
Write a function that parses the array and puts the values in some variables.
Before asking here, I was reading: https://docs.racket-lang.org/guide and also https://docs.racket-lang.org/reference
My approach is as follows:
I am using a byte string because it seems it can be used to mimic the C++/C arrays.
I am using tail recursion to traverse the "array".
Questions:
1) In C, I always use the return value of a function as an error code: 0 is ok and any negative value is an error. With Racket, I am using multiple return values to indicate: a) the return code, b) the processed value(s), i.e. something like:
(values return_code out1 out2 ...)
What do you think? Do you recommend the use of exceptions for error handling?
2) What's the best approach to process arrays in Racket? I mean, the best according to the offered by Racket and to achieve a good performance.
Thanks!
Edit1:
Regarding my first question (the return codes), I am calling many functions and I would like to return an exit code that helps me to know if there was an error inside the function. This is a sample code:
#lang racket
(define (is_valid in)
(cond
[(and (>= in 10) (<= in 15)) #t]
[else #f]))
(define (copy_values in)
(define len (bytes-ref in 2))
; 3 is where the string "ABCD" begins
(define str (subbytes in 3 (+ 3 len)))
(define numbers (subbytes in (+ 3 len)))
(values str numbers))
(define (parse in)
(define type (bytes-ref in 0))
(if (is_valid type)
(let ()
(define-values (str numbers) (copy_values in))
(values #t str numbers))
(values #f 0 0)))
; format: type strlen
; len |-- str --| | -- numbers -- |
;
(define input1 (bytes 10 10 4 65 66 67 68 110 120 130 140 150))
(define input2 (bytes 1 10 4 65 66 67 68 110 120 130 140 150))
(parse input1)
(parse input2)
This is the output in DrRacket:
Welcome to DrRacket, version 6.7 [3m].
Language: racket, with debugging; memory limit: 128 MB.
#t
#"ABCD"
#"nx\202\214\226"
#f
0
0
Look how I use the (values ...) stuff, does that make sense?
To return a value to the operating system, use (exit [v]).. Other values should probably go to standard out and/or standard error. This means writing them before the program exits.
In terms of assigning the values of an array to variables, there are many ways to do it depending on how lexical scope comes into play within the function and module and across modules. Also reference semantics versus value semantics are considerations.
Finally, there is no compelling reason to choose recursion over an explicit loop when dealing with a byte-string. bytes-length is a low level primitive implemented in C and will return the length needed for a loop without testing for an empty byte-string.

Issue with NetLogo map

When I enter (map [?1 + ?2] [1 2 3] [2 4 6]) into the command center, it works fine. But when I enter this code
to test
(map [?1 + ?2] [1 2 3] [2 4 6])
end
I get the diagnostic: "Expected command." with map highlighted. I'm stumped. Suggestions would be appreciated. Thanks.
(I'm using NetLogo 5.1.0.)
The problem is that map is not considered a command (as the diagnostic says). When I replace map with foreach (and put the function at the end) it's fine.
In fact, that's what I really wanted in the first place. I was using map for it's side-effects of running through multiple lists rather than to return a list. My mistake.
For user convenience, the command center allows you to set the "context" of your commands and does a little extra interpretation depending on that context. The problem is not that the map reporter is failing, but that it reports a list, and you need a command saying what to do with that list.
After you enter (map [?1 + ?2] [1 2 3] [2 4 6]) in the command center, look not just at the result but also at the code actually executed (right above the result). If you put that code in your test procedure, it will work.
you code does not work because you are producing a new list with map but you are not assigning that list to any variable. You are right that map is not a command primitive, it is a reporter primitive, so it returns a value and you have to put that value somewhere, like print it on the screen:
to test
print (map [?1 + ?2] [1 2 3] [2 4 6])
end
or store it in a variable:
to test
let a-variable (map [?1 + ?2] [1 2 3] [2 4 6])
print a-variable
end

Writing a macro to swap the values of two symbols

I can't think of any possible use case for this, but as an exercise to try to wrap my mind further around Clojure's macros, I'm trying to write a macro that will swap the values assigned to two symbols.
Here are two things that I tried:
Method 1:
(defmacro swap [x y]
`(let [tmp# ~x]
(def x ~y)
(def y ~tmp#)))
Method 2:
(defmacro swap [x y]
`(let [tmp# ~x]
(alter-var-root #'x (fn [] ~y))
(alter-var-root #'y (fn [] ~tmp#))))
Here is the code I use to test it:
(def four 4)
(def five 5)
(swap four five)
(printf "four: %d\nfive: %d" four five)
Expected output:
four: 5
five: 4
However, using either version of the macro, I get a java.lang.RuntimeException: Unable to resolve symbol: tmp# in this context. Am I using auto gensym incorrectly?
Using method 1, I was able to get it to run by changing the last line to (def y tmp#))) (taking out the ~ before tmp#), however I get the output four: 4\nfive: 5 which is not swapped.
Ignoring the fact that mutating vars like this is a bad idea, let's assume you really want to do it anyway. Your problem is two-fold:
You have an unquote on ~tmp#, where you just want tmp#
You're missing an unquote on x and y: you want to (def ~x ~y) and (def ~y tmp#)
The version you wrote always assigns to the vars named x and y, instead of modifying the vars provided by the user.