Attributes and Instances - Scheme, Racket: unbound identifier in module - attributes

I am trying to define a kind of dataset for an exercise I was asked to do. This is the code:
#lang racket
(
(
(pers(sol nub lluv))
(tmp numeric)
(hum numeric)
(vin (yes no))
(class (+ -))
)
;Instances
(sol 30 40 no +)
(lluv 24 70 yes -)
(sol 20 80 no +)
)
The problem is when I run this code I get the following message:
pers: unbound identifier in module in: pers
Do I have to define the identifiers in a different way?
Thanks for your answers!

Well, actually it is a file so there's no need to write "#lang racket". The thing is that I thought I had to run it but it was ok like that according to the exercise.
The next exercise was to read it and the code was the following:
#lang racket
(define (read-file filename)
(define datafile (with-input-from-file filename read))
datafile
)
;Store file info in a variable
(define fileinfo (read-file "filewithinfo.scm"))
So after running that, on console I could write "fileinfo" to display the file information, which was:
>fileinfo
'(((pers (sol nub lluv)) (tmp numeric) (hum numeric) (vin (yes no)) (class (+ -))) (sol 30 40 no +) (lluv 24 70 yes -) (sol 20 80 no +))
More info: https://en.wikibooks.org/wiki/Scheme_Programming/Input_and_Output

Related

Is there an easy way to convert strings to variable names (identifiers) in Racket?

I am pretty new in Racket and I have tried to do something that is really easy in other languages, such as PHP, which is converting a string to a variable name.
Something like:
#lang racket
(define t0 3)
(display t0) ; It outputs 3
(define (symbol? (string->symbol "t1")) 2 )
(display t1) ; It would output 2, however it throws an error :(
Is there a way to convert a string to identifier? Because I need to define variable names from strings, dynamically.
You can do what you want with the help of namespaces. However look into hash tables first.
#lang racket
(define-namespace-anchor here)
(define ns (namespace-anchor->namespace here))
(define foo 42)
(parameterize ([current-namespace ns])
(namespace-variable-value (string->symbol "foo")))
The output of this program is 42.
Indeed soegaard hash tables are a very good solution, here is an example:
#lang racket
(define ht (make-hash))
(define sx "x")
(define sy "y")
(define sr "r")
(hash-set! ht sx 2)
(hash-set! ht sy 3)
(define r (+ (hash-ref ht sx) (hash-ref ht sy))) ;do calculation (+ 2 3)
(hash-set! ht sr r)
(hash-ref ht sr) ; it will output 5

How can I delete silence from the middle of .wav files in Audacity but not the edges?

I am trying to delete silence from an audio file using Audacity. There is a Nyquist plugin called Trim Silence which deletes silence from the start and end of a file, but not the middle. I would like to invert this, and delete silence from everywhere except the start and end.
I think the function below is the relevant part of the plugin. How should I change it to get a truncate-internal-silences function? (I don't know any Nyquist, or Lisp, so I'm struggling to understand what it currently does, let alone change it.)
Entirely different approaches also welcome - this is just my current best guess at how to edit my many audio files.
(defun trim-silence ()
;; Nyquist plug-ins cannot return 'no audio', so trap as error.
(if (< (get '*selection* 'peak-level) threshold)
(throw 'error (format nil "Error.~%All selected audio in the ~a selected track~%~
is below the silence threshold.~%~%~
Try setting the threshold to a~%~
lower (more negative) dB level."
(add-num-suffix (get '*track* 'index)))))
(if (> len (* limit *sound-srate*)) ;max length in samples
(throw 'error (format nil "Error.\nMax RAM usage by Trim Silence is set to ~a GB.~%This allows a maximum duration ~
for a ~a~%track at ~a Hz of ~a.~%Selected track is ~a.~%"
RAM-limit
(if (arrayp *track*) "stereo" "mono")
(round *sound-srate*)
(to-hhmmss limit)
(to-hhmmss (get-duration 1)))))
(let* (;; ratio provides tighter trimming for short selections
;; while maintaining reasonable speed for long selections
(ratio (max 10 (min 200 (round (/ len 100000.0)))))
(my-srate (/ *sound-srate* ratio))
(mysound (convert *track* ratio))
(limits (get-clip-limits)) ; (list start, end) times of audio clips
(clip-start (if (first limits)
(abs-to-relative-time (nth 0 limits)))) ; nil id invalid
(clip-end (if (second limits)
(abs-to-relative-time (nth 1 limits))))) ; nil if invalid
;loop through samples and mark start and end
(setf result (find-sil mysound clip-start clip-end))
(let ((start (if clip-start
(max clip-start
(- (/ (first result) my-srate) min-start-silence))
0))
(end (if clip-end
(min (+ (- (get-duration 1) (/ (second result) my-srate))
min-end-silence)
clip-end)
(get '*selection* 'end))))
;; ensure at least 1 sample remains
;; This should never happen.
(if (>= start end)
(setq start (- end (/ *sound-srate*))))
; trim
(multichan-expand #'extract-abs start end (cue *track*)))))

LISP how to call an object from a variable after taking out the name of the object from another variable

I am still very beginner in LISP and hope that you all could give me some suggestions on how to solve the following problem.
(CG-USER(1):defstruct Test()
(TestValue 10)
(TestChild 'none)
)
TEST
CG-USER(2): (defun testvalue(item)
(slot-value item 'TESTCHILD))
TESTVALUE
CG-USER(3):(setf TestObject(make-Test :TestChild '(TestObject2 B C)))
#S(TEST :NIL NIL :TESTVALUE 10 :TESTCHILD (TESTOBJECT2 B C))
CG-USER(4): (setf TestObject2(make-Test :TestChild '(D E F)))
#S(TEST :NIL NIL :TESTVALUE 10 :TESTCHILD (D E F))
CG-USER(5): (setf aaa (car (testvalue TestObject)))
TESTOBJECT2
CG-USER(6): (testvalue aaa)
Error: The slot TESTCHILD is missing from the object TESTOBJECT2 of class #<BUILT-IN-CLASS SYMBOL> during
operation SLOT-VALUE
[condition type: PROGRAM-ERROR]
The following is my code. As you can see, I am trying to read the details in the object TestObject2 through the function testvalue . My main purpose is to able to determine the name of the object (TestObject2) from the another object first (in this case, TestObject) as I do not know the name of the name TestObject2 yet.
But however, once I managed to successfully retrieve the name TestObject2 , when I try to access the elements inside the object (TestObject2) , it no longer identify the variable holding TestObject2 (in this case, "aaa") as an object. Thus, it could not read the testvalue of it, resulting in the error.
I am very beginner at LISP and I could not figure out on how to solve this. It would be really great if anyone could provide a sample solution for this. Thanks.
P/S: Also, may I ask what is the NIL NIL in this line? And any way to remove it?
#S(TEST :NIL NIL :TESTVALUE 10 :TESTCHILD (D E F))
Second question:
(defstruct Test()
(TestValue 10)
(TestChild 'none))
Let's format above slightly different:
(defstruct Test ; the structure has a name `TEST`
() ; the first slot is named `NIL`
(TestValue 10) ; the second slot is named `TESTVALUE`
(TestChild 'none)) ; the third slot is named `TESTCHILD`
So, it makes sense to remove the first slot... ;-) and we get:
(defstruct Test ; the structure has a name `TEST`
(TestValue 10) ; the first slot is named `TESTVALUE`
(TestChild 'none)) ; the second slot is named `TESTCHILD`
First question:
TESTOBJECT2 is a symbol. If the symbol has a value, you can retrieve it with the function SYMBOL-VALUE.
(symbol-value 'testobject2)
Generally you want to slim your code a bit:
CL-USER 42 > (defstruct test
(value 10)
(child 'none))
TEST
In above we don't need the test prefix. DEFSTRUCT already creates accessors with TEST- as the prefix.
CL-USER 43 > (setf test-object (make-test :child '(test-object2 b c)))
#S(TEST :VALUE 10 :CHILD (TEST-OBJECT2 B C))
Note that in your example and in above code, the :child is not a structure. It is just a list of three symbols.
CL-USER 44 > (setf test-object2 (make-test :child '(d e f)))
#S(TEST :VALUE 10 :CHILD (D E F))
Again, the child of above is a list of three symbols.
CL-USER 45 > (setf aaa (car (test-child test-object)))
TEST-OBJECT2
Above: The first of that list is the symbol TEST-OBJECT2.
CL-USER 46 > (test-value (symbol-value aaa))
10
Above: we can retrieve the symbol value of the symbol TEST-OBJECT2, which is the value of the variable AAA.

Haskell-style sections in Common Lisp

In Haskell, if I have a lambda that looks like the following
(\x -> doStuff x y)
where y is from the surrounding scope, I could section it and turn it into
(`doStuff` y)
which is shorter and more concise (and one of the things I love the most about Haskell).
Now, in Common Lisp I would write the equivalent code as
(lambda (x) (do-stuff x y))
And this is actually a very common thing for me to be writing, but I feel even that tiny bit of boilerplate bothers me somewhat, so I wonder if there is a way to get something like the Haskell-style sections in Common Lisp?
Unless you are more experienced, I would propose that you learn to write Lisp in Lisp, not how to write Haskell in Lisp. The latter is not a good idea. Haskell works very different.
Lisp does not do any 'currying' (or schönfinkeling ;-) ).
You can write it as:
CL-USER 5 > (defun curry (fn arg) (lambda (&rest args) (apply fn arg args)))
CURRY
CL-USER 6 > (mapcar (curry #'expt 2) '(2 3 4 5 6))
(4 8 16 32 64)
It costs a bit efficiency that way, though.
CL-USER 7 > (mapcar (lambda (base) (expt base 2)) '(2 3 4 5 6))
(4 8 16 32 64)
I personally prefer the latter, because I have a real readable name for the variable. This helps in a debugger, where I see then a backtrace. Tools like these are probably more important in Lisp, than in Haskell.
CL-USER 12 > (mapcar (lambda (base) (expt base 2)) '(2 3 "four" 5 6))
error. Let's look at the backtrace:
CL-USER 12 : 1 > :bb
...
Condition: In EXPT of ("four" 2) arguments should be of type NUMBER.
Call to SYSTEM::ARGS-TO-BINARY-ARITHMETIC-FN-NOT-OF-TYPE {offset 189}
SYSTEM::FN-NAME : EXPT
SYSTEM::ARG1 : "four"
SYSTEM::ARG2 : 2
TYPE {Closing} : NUMBER
Interpreted call to (SUBFUNCTION :ANONYMOUS SYSTEM::ANONYMOUS-LAMBDA):
BASE : "four"
Now I can see that the thing has a name. I was passing the string "four" to the function with a variable named base.
Interactive development with REPL and debugging tools is common. Best prepare the code to be useful for this development style. Common Lisp is not optimized to provide full program compilers with extensive type checking - like in Haskell.
One of the main problems of Lisp is that it can be very hard to find out what a piece of code really does. The default (strict functional programs with prefix syntax) is relatively easy to understand. But there are many possibilities to change the meaning of code in Lisp (macros, read macros, symbol macros, the Meta Object protocol, advising, ...).
First rule: if you are writing basic Lisp code, stick with the basic syntactic and semantic possibilities. Write defensively. Expect that someone else needs to understand the code. For that the code should be readable, easy to understand, use common idioms and it should be debuggable.
In Haskell many people with math background want to write code in a very compact way with a high level of abstraction. You can do that in Lisp, too. But for ordinary code I would not go that route and for larger pieces of code, Lisp often uses other mechanisms (code transformations via macros, ...).
You can develop arbitrary special syntax for such forms. There're multiple variants. I, for instance, use a Clojure-inspired sharp-backquote syntax. Using it, your form will look like this:
#`(do-stuff % y)
I don't think you can do it directly, but...
If you know that you always want to do something that is equivalent to (lambda (x) (fun x lexical)) and simply want a shorter way of expressing that, you could, in theory, use a macro.
I would, personally, advise against doing so, (lambda (x) (fun x lex)) doesn't take much typing and removes one layer of obscurity from your code. But if it is a pattern that is sufficiently common that it warrants special handling, something like the following might do:
(defmacro section (function lexical)
(let ((sym (gensym))
`(lambda (,sym) (,function ,sym ,lexical))))
That makes the Haskell section:
(`doStuff` y)
become the Common Lisp section:
(section dostuff y)
I don't, as such, find it more readable, at least in the short, but if it was something that I did see again and again, I would indeed consider (and have done, more for experimental purposes than anything else) a macro to make it quicker (I have a half-baked macro, somewhere, that allows you to do things like (_ func _2 lexical _1) -> *(lambda (a b) (func b lexical a)) and that is sometimes handy, but doesn't really improve readability).
There's a sharp backquote read macro in Let Over Lambda that could work for this case:
CL-USER>
(print
'#`,(+ a1 y))
(LAMBDA (A1) (+ A1 Y))
(LAMBDA (A1) (+ A1 Y))
CL-USER>
(let ((y 2))
(mapcar #`,(+ a1 y)
(list 1 2 3 4)))
(3 4 5 6)
CL-USER>
This approach is very similar to the technique mentioned by #Vsevolod Dyomkin. Hoyte's version does have a few extra features, like building a lambda with any number of arguments. On the other hand, it's a bit harder to parse, because it's being expressed at one level higher notation, where in order to eval a form you have to unquote the backquote (using ',' in this example).
Scheme has the cut macro (in SRFI-26), which allows you to specify holes in a procedure call with <>. For example:
(cut doStuff <> y) ;; same as (lambda (x) (doStuff x y))
(cut - 5 <> 6 <> 7) ;; same as (lambda (x y) (- 5 x 6 y 7))
You could probably define something similar in CL.
I also missed the ease of Haskell-style function currying and composition when in common lisp. As a result I wrote the following package which defines reader macros for concise curry and composition in lisp (it uses the alexandria functions).
http://eschulte.github.io/curry-compose-reader-macros/
With this package (mapcar (compose (curry #'* 2) (curry #'+ 1)) (list 1 2 3 4)) becomes (mapcar [{* 2} {+ 1}] (list 1 2 3 4)). I now use this in nearly all of my CL projects and find it greatly reduces code size and increases readability.
The alexandria package exports the symbols curry and rcurry.
So in your case you just do
(alexandria:rcurry function arg) e.g., (rcurry #'do-staff y).
Rcurry and curry return functions so you need to funcall the result as usual.

Define global from within a function

I need some function which among other stuff would define a new global symbol. So that I could use it like this:
(define (func-prototype symbol value comment)
(define symbol value) ; this should somehow be reformulated
(format "~a=~a !~a\n" symbol value comment))
(define string-list (map func-prototype
'((s1 1 "first value")
(s2 20 "second value")
(s3 300 "third value))))
and be able to get the following results:
> string-list
'("s1=1 !first value\n"
"s2=20 !second value\n"
"s3=300 !third value\n")
> s1
1
> s2
20
> s3
300
Can this be implemented as a function or it is possible to do that only with the help of macros? Could you please suggest any possible implementations or at least give some hints/references that might be helpful?
I'd rethink the general approach, making it simpler. My suggestion: define a global hash table and inside the function add bindings to it, for example:
(define value-map (make-hash))
(define (func-prototype symbol value comment)
(hash-set! value-map symbol value)
(format "~a=~a !~a\n" symbol value comment))
Use it like this:
(define string-list
(map (lambda (lst)
(apply func-prototype lst))
'((s1 1 "first value")
(s2 20 "second value")
(s3 300 "third value"))))
string-list
=> '("s1=1 !first value\n"
"s2=20 !second value\n"
"s3=300 !third value\n")
And wherever you need to refer to one of the symbols in the hash table, do this:
(define (get key)
(hash-ref value-map key))
(get 's1)
=> 1
(get 's2)
=> 20
(get 's3)
=> 300
In general it is not possible to accomplish what you are trying to accomplish in the way you described. Your only hope would be to write stuff out to a file and then load that file into an interactive session. But even then.
In scheme you can't introduce top-level names, such as your desired s1, s2, and s3, except at the top-level. To do so, you could define a macro as:
>(define-syntax define-foo
(syntax-rules ()
((_ name value)
(define name value))))
>(define-foo s1 1)
<undefined>
> s1
1
If you try to use that macro in a function, it is no dice because the body of a function must end with an expression and any definition forms, like what the above macro would expand into, become local variables. That is:
(define (func-prototype name value comment)
(define-foo name value)
name)
>(func-prototype 's1 1 "com")
1
> s1
<error>
One approach that you could take that would work if your string-list is a constant would be as such:
> (define-syntax declare-variables
(syntax-rules ()
((_ (name value comment) ...)
(begin
(define name value)
...))))
> (declare-variables (s1 1 "com") (s2 20 "com") (s3 300 "com"))
> s1
1
This gets it done (I've ignored using 'comment') but, as I said, requires a compile time string-list.
One possibility you might think would work, but wouldn't, would be to use eval as:
(eval '(define s1 1) (environment ...))
but 'eval' only works for expressions, not declarations. Which gets me back to 'load' as a possibility.
First, consider whether you really want to do this, or whether a different solution (like a hash table) would work as well.
You can do this with reflection and dynamic evaluation using the eval procedure.
;; define-variable-with-value! : symbol any -> void
(define (define-variable-with-value! name value)
(eval `(define ,name (quote ,value))))
The quote is important; otherwise you risk reinterpreting a value as an expression to evaluate. To see the difference, consider the example
(define-variable-with-value! 'x (list 'error "kaboom"))

Resources