I need to write a code that take a element and add to list that give as input, and return an new list instead of old list.. after than i will do recurssion and i need new list... below code is working fine.. however i try to reduce all set! that because confuse me and sometime i take error that i cannot solve..
How can i do this operation without set! ? I try just cons, list and append but none of them do this job.
(set! list (cons element list))
Thank you..
Just (cons element list) is enough.
Your code is altering the contents of list variable. We don't normally do that, in functional style, and the only way to do this is to use set! as you did.
But to just return the new list, which has a new element on top of it, the call (cons element list) is enough:
...
(let ((newlist (cons element oldlist)))
.....
..... use newlist and oldlist as needed
Related
TL;DR
What I'm looking for is a combination of the functions send/apply and dynamic-send. So that it finds a method of an object based on a symbol and unpacks a list of arguments.
Background and more info
For a project I am sending some "commands" trough the network with Racket's tcp-connect. At the receivers end this command should execute a method from a class and pass along its parameters.
Consider the following received 'message':
(define message (list 'set-switch! '3 'on))
(define method-name (car msg)) ;'set-switch!
(define parameters (cdr msg)) ;(list '3 'on)
And the following class:
(define light%
(class object%
(super-new)
...
(define/public (set-switch! id mode)
(vector-set! switches id mode))))
The problem now is that when executing this statement
(dynamic-send light-class method-name parameters)
it perfectly finds the method set-switch! but it calls it with only one parameter (list '3 'on).
The Racket docs mention those three functions for classes:
(send obj-expr method-id arg) which just executes a method of an object
(send/apply obj-expr method-id arg-list-expr) which executes a method AND unpacks the argument list
(dynamic-send obj method-name v) which finds a method-name based on a symbol
What I think I need is something like (dynamic-send/apply obj method-name arg-list-expr) which combines the last two mentioned.
Note: I know that I could just simply accept lists as parameters and use car and cdr in the functions itself to get the right values. But that's not what I want.
dynamic-send is a function (also known as procedure; e.g., car, vector-set!, +), so you can use apply:
(apply dynamic-send light-class method-name parameters)
Or even simply:
(apply dynamic-send light-class message)
The reason why send has the send/apply variant is that send is a form (also known as syntax; e.g., let, define, if), so apply doesn't work and hence send/apply is separately provided.
This time my problem is mostly with Racklog. I guess. Could also be the Racket syntax this time.
The idea is rather simple. I have a logic-base made up of places and objects and I just wanted to try out printing all the objects using the %bag-of primitive.
My logic-base looks like this:
(define %contains
(%rel ()
[('bridge 'phaser)]
[('engine_room 'toolkit)]
[('toolkit 'screwdriver)]
[('toolkit 'tricorder)]
[('inventory '(communicator, no_tea))]
)
)
Now I have my predicate which is the following one. It should be simply called with the query "(%which () (%list_objects 'toolkit))" and then give out all the items inside the toolkit for example.
(define %list_objects
(%rel (place)
[(place)
(%which (objects)
(%let (x)
(%bag-of x (%contains place x)
objects)))]
)
)
The weird thing is when I just thake the part from the "%which (objects)...)" onwards and throw it directly into the listener, it works perfectly fine. But if I'm using it inside the predicate, it throws this exception:
"application: not a procedure;
expected a procedure that can be applied to arguments
given: '((objects screwdriver tricorder))
arguments...: [none]"
I tried rearranging the code several times, but right now I'm quite stumped about what I did wrong. I would appreciate a little hint what I as a total newbee to Scheme and Racket missed out here. My thanks in advance!
The problem is that the goal (%which ...) returns an answer (not a new relation). Therefore %list_objects can't be used in the way you want.
Maybe this works for you?
#lang racket
(require racklog)
(define %contains
(%rel ()
[('bridge 'phaser)]
[('engine_room 'toolkit)]
[('toolkit 'screwdriver)]
[('toolkit 'tricorder)]
[('inventory '(communicator, no_tea))]))
(define %list_objects
(%rel (place)
[(place)
(%let (x) (%contains place x))]))
(%which (x) (%list_objects x))
(%more)
(%which (bag) (%let (x) (%bag-of x (%list_objects x) bag)))
(define tools-in-toolkit (map cdar (%find-all (tool) (%contains 'toolkit tool))))
(define %in-toolkit
(%rel (tool)
[(tool) (%member tool tools-in-toolkit)]))
(%find-all (tool) (%in-toolkit tool))
Output:
'((x . bridge))
'((x . engine_room))
'((bag bridge engine_room toolkit toolkit inventory))
'(((tool . screwdriver)) ((tool . tricorder)))
How to add a common prefix/suffix to a list of strings?
For example:
From ("abc" "123" "xy")
To ("pre_abc" "pre_123" "pre_xy")
Try
(mapcar (lambda (c) (concat "pre_" x)) '("abc" "123" "xy"))
In Emacs without third-party libraries you use mapcar function to apply a function to every element of the list, as #sds have shown. However if you program in Elisp heavily, i recommend installing 2 third-party libraries, dash.el for list manipulation and s.el for string manipulation. These libraries introduce a huge amount of auxiliary functions with a consistent naming scheme. dash.el also have anaphoric versions for many functions, which makes code even less verbose. So to add a prefix for every string in a list you could use --map and s-prepend (s-append for suffixes):
(--map (s-prepend "x" it) '("a" "b" "c")) ;; => ("xa" "xb" "xc")
The operation to prepend is (concatenate 'string <strings ...)
So you could achieve your goal with
(cl-loop
for item in '("abc" "123" "xy")
collect (concatenate 'string "pre_" item))
A more general way to compose/generate strings would be to use format
using format would be
(cl-loop
for item in '("abc" "123" "xy")
collect (format nil "pre_~S" item))
Note using cl-lib package
I will describe my problem on example.
I'll get (play '(left nothing right left)). Some of the names in the list are real procedures, others i want to skip.
(define (left)
'left
)
I need to interpret procedures with names in the list. What is the solution?
When I try ( (car '(left nothing right left))) I get error : procedure application: expected procedure, given: left (no arguments)
(car '(left nothing right left)) evaluates to the symbol left, which is the name of a procedure, but not actually a procedure, so you can't call it.
You'll want to build an association list mapping symbols to procedures:
(define actions `((left . ,(lambda () 'left))
(right . ,(lambda () 'right))
(nothing . ,(lambda () (display "I'm staying put")))))
then you can call the appropriate function for the first element in your list as
((cdr (assoc (car '(left nothing right left)) actions)))
You can also use quasiquoting to construct a list containing a mixture of symbols you want evaluated and others you don't, e.g.
(play `(,left nothing nothing ,right nothing))
left and right will expand to whatever you've defined them as (such as a procedure) while nothing is not un-quoted so it will be left as a symbol. play would then have to test each member to see if it's a procedure, something like:
(define (play xs)(for-each (lambda (x)(if (procedure? x)(x) x)) xs))
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.