I couldn't find a way to define a static field in racket. By static, I mean a field that belongs to the entire class and not to an instance.
(define counter% (class object%
(field (current-count 0))
(super-new)
(define/public (get-count)
current-count)
(define/public (next)
(set! current-count (+ current-count 1))
(set! total (+ total 1))
(list current-count total))))
(define c1 (new counter%))
(define c2 (new counter%))
(send c1 next)
(send c1 next)
(send c1 next)
(send c2 next)
So total in this example should be a static field and the output should be:
'(1 1)
'(2 2)
'(3 3)
'(1 4)
How about this solution?
#lang racket
(define counter%
(let ([total 0])
(class object%
(field (current-count 0))
(super-new)
(define/public (get-count)
current-count)
(define/public (next)
(set! current-count (+ current-count 1))
(set! total (+ total 1))
(list current-count total)))))
(define c1 (new counter%))
(define c2 (new counter%))
(send c1 next)
(send c1 next)
(send c1 next)
(send c2 next)
Related
I need to iterate through a list with sublists in Racket using list iteration and filtering, one of the lists is a nested list, I tried using "list?" and "car" to iterate inside but of course that would only apply to the first value of the sublist.
Is there a way to iterate through the whole nested list using list iteration and filtering?
(define (count-evens lst)
(length
(filter
(lambda (x)
(cond
[(and (list? x)
(and (number? (car x))
(eq? (modulo (car x) 2) 0)))
#t]
[(and (number? x)
(eq? (modulo x 2) 0))
#t]
[else
#f]))
lst)))
(count-evens '(1 2 5 4 (8 4 (b (10 3 3))) 3))
=> 3
Should return => 5
I would use a recursive function to do this but the assignment doesn't allow it.
"...assignment doesn't allow [recursive functions]"
Not sure what is allowed for this assignment, but
in ye olden days we processed recursive data structures with stacks...
(define (count-evens lst)
(define (lst-at stack) ;; (car stack) = index in deepest sub-list
;; produce list cursor within lst indexed by stack
(do ([stack (reverse stack) (cdr stack)]
[cursor (list lst) (list-tail (car cursor) (car stack))])
((null? stack) cursor)))
(do ([stack (list 0)
(cond
[(null? (lst-at stack))
(cdr stack)] ;; pop stack
[(pair? (car (lst-at stack)))
(cons 0 stack)] ;; push stack
[else ;; step through current (sub)list
(cons (+ 1 (car stack)) (cdr stack))])]
[count 0
(let ([item (car (lst-at stack))])
(if (and (number? item) (even? item)) (+ 1 count) count))])
((null? (lst-at stack)) count)))
> (count-evens '(1 2 5 4 (8 4 (b (10 3 3))) 3)) ;=>
5
here's the make-counter procedure and calls to it
(define make-counter
(let ((glob 0))
(lambda ()
(let ((loc 0))
(lambda ()
(set! loc (+ loc 1))
(set! glob (+ glob 1))
(list loc glob))))))
> (define counter1 (make-counter))
counter1
> (define counter2 (make-counter))
counter2
> (counter1)
(1 1)
> (counter1)
(2 2)
> (counter2)
(1 3)
> (counter1)
(3 4)
i can't understand why does glob behaves as a class variable, while loc behaves as an instance variable.
It may be easiest to consider when each part of the code is run. You evaluate
(define make-counter (let ((0 glob)) ...))
just once, so the let is evaluated just once. That means that there's only one binding, and its value is shared by everything within the body of the let. Now, what's in body of the let? It's a lambda function, which becomes the value of make-counter:
(lambda () ; this function is the value of make-counter
(let ((loc 0)) ; so this stuff gets execute *each time* that
(lambda () ; make-counter is called
... ;
))) ;
Now, every time you call make-counter, you evaluate (let ((loc 0)) (lambda () …)), which creates a new binding and returns a lambda function that has access to it (as well as to the global binding from outside.
So each result from calling make-counter has access to the single binding of glob, as well as to access to a per-result binding of loc.
Let us examine the program:
(define make-counter
(let ((g 0))
(lambda ()
(let ((l 0))
(lambda ()
(set! l (+ l 1))
(set! g (+ g 1))
(list l g))))))
The program illustrates how an abstraction (lambda-expression) creates
a closure that contains references to the free variables.
It would be helpful to see and inspect the free variables explicitly,
so let's pretend we want to run the program above in a language
that doesn't support lambda. In other words, let try to rewrite
the program into one that uses simpler constructs.
The first is to get rid of assignments. Let's allocate a box
(think vector of length one) that can hold one value.
An assignment can then change the value that box holds using set-box!.
; Assignment conversion: Replace assignable variables with boxes.
; The variables l and g are both assigned to
(define make-counter
(let ((g (box 0)))
(lambda ()
(let ((l (box 0)))
(lambda ()
(set-box! l (+ (unbox l) 1))
(set-box! g (+ (unbox g) 1))
(list (unbox l) (unbox g)))))))
This program is equivalent to the original (try it!).
The next step is to annotate each lambda with its free variables:
(define make-counter
(let ((g (box 0)))
(lambda () ; g is free in lambda1
(let ((l (box 0)))
(lambda () ; g and l are free lambda2
(set-box! l (+ (unbox l) 1))
(set-box! g (+ (unbox g) 1))
(list (unbox l) (unbox g)))))))
Now we are ready to replace lambda with explicit closures.
A closure holds
i) a function with no free variables
ii) values of the free variable at the time the closure was created
We will use a vector to store i) and ii).
(define (make-closure code . free-variables)
(apply vector code free-variables))
We can get the function with no free variables like this:
(define (closure-code closure)
(vector-ref closure 0))
And we can the i'th free variable like this:
(define (closure-ref closure i)
(vector-ref closure (+ i 1)))
To apply a closure one calls the function with no free variables (code)
with both the closure (which code will need to find the values of the
free variables) and the actual arguments.
(define (apply-closure closure . args)
(apply (closure-code closure) closure args))
Here are the code corresponding to the lambda1
(define (lambda1 cl) ; cl = (vector lambda1 g)
(let ((g (closure-ref cl 0))) ; g is the first free variable of lambda1
(let ((l (box 0)))
(make-closure lambda2 g l))))
Since lambda1 was a function of no arguments, the only input is the closure.
The first thing it does is to retrieve the free value g.
Note that lambda1 returns a closure: (make-closure lambda2 g l)
Here we see that when the closure for lambda2 is made the values of g and l
are preserved.
Now lambda2:
(define (lambda2 cl) ; cl = (vector lambda2 g l)
(let ((g (closure-ref cl 0))
(l (closure-ref cl 1)))
(set-box! l (+ (unbox l) 1))
(set-box! g (+ (unbox g) 1))
(list (unbox l) (unbox g))))
Finally make-counter which simply makes a lambda1-closure:
(define make-counter (make-closure lambda1 (box 0)))
We are now ready to see our program in action:
(define counter1 (apply-closure make-counter))
counter1
(define counter2 (apply-closure make-counter))
counter2
(apply-closure counter1)
(apply-closure counter1)
(apply-closure counter2)
(apply-closure counter1)
The output is:
'#(#<procedure:lambda2> #&0 #&0)
'#(#<procedure:lambda2> #&0 #&0)
'(1 1)
'(2 2)
'(1 3)
'(3 4)
This means out program works in the same way as the original.
Now however we can examine the free variables of the two counters:
> counter1
'#(#<procedure:lambda2> #&4 #&3)
> counter2
'#(#<procedure:lambda2> #&4 #&1)
We can check that the two counters share the same g:
> (eq? (closure-ref counter1 0)
(closure-ref counter2 0))
#t
We can also check that they have two different boxes containing l.
> (eq? (closure-ref counter1 1)
(closure-ref counter2 1))
#f
I've got some function func and want to apply it on a list lst, so I used map but I need to have the first and last element of the list evaluated with some other function func2.
So basically I want this:
(map (lambda (x)
(cond [(isBeginningOfList? lst) (func2 x)]
[(isEndOfList? lst) (func2 x)]
[else (func x)]))
lst)
Obviously this doesn't work.
How can I achieve this functionality?
Can I somehow get a key of each list entry? Like lambda(key,val) and then compare (equal? key 0) / (equal? key (length lst))?
There's for/list with in-indexed and that does what you describe:
(define (f lst f1 f2)
(define last (sub1 (length lst)))
(for/list (((e i) (in-indexed lst)))
(if (< 0 i last)
(f1 e)
(f2 e))))
then
> (f '(1 2 3 4 5) sub1 add1)
'(2 1 2 3 6)
You can use a map on all the elements except the first and the last one and treat those two separately. In this way you avoid those comparisons which you would do for every element.
(define special-map
(λ (lst f1 f2)
(append (list (f1 (car lst)))
(map f2 (drop-right (cdr lst) 1))
(list (f1 (last lst))))))
Example
Let's try to increment the first and the last elements and decrement all the others.
> (special-map '(1 2 3 4 5) add1 sub1)
'(2 1 2 3 6)
Later edit
I changed (take (cdr lst) (- (length lst) 2)) with (drop-right (cdr lst) 1).
i am new to racket. i am trying create a list from the input of the user and when the value 0 is entred the first three elements are printed.
here is the code:
#lang racket
(define lst '())
(define (add)
(define n(read))
(if (= n 0)
;then
(
list (car lst) (cadr lst) (caddr lst)
)
;else
(
(set! lst (append lst (list n)))
(add)
)
)
)
(add)
i tested the program with the values 1 2 3 4 5 0
but i keep getting this error:
application: not a procedure;
expected a procedure that can be applied to arguments
given: #<void>
arguments...:
'(1 2 3)
can anyone help me figure out what's wrong.
If you have more than one expression in the "then" or "else" parts, you must enclose them inside a begin, because a pair of () in Scheme are used for function application - that explains the error you're getting. Try this:
(define (add)
(define n (read))
(if (= n 0)
; then
(list (car lst) (cadr lst) (caddr lst))
; else
(begin
(set! lst (append lst (list n)))
(add))))
I had a similar problem, in a function i called a parameter with the same name of a structure, so, trying to create an instance of that structure i got the same error.
example:
> (struct example (param1 param2) #:transparent)
> (define e (example 1 2))
> e
(example 1 2)
> (define (fn e)
(example (example-param1 e) 0))
> (fn e)
(example 1 0)
> (define (fn example)
(example (example-param1 example) 0))
> (fn e)
application: not a procedure;
expected a procedure that can be applied to arguments
given: (example 1 2)
arguments...:
I hope this helps
Your code have a few problems, for example it will fail if you enter less than 3 elements. Also, it is not considered good style to define variables at the module level.
I'd suggest the following:
(define (add)
(define (sub cnt lst)
(define n (read))
(if (= n 0)
(reverse lst)
(if (< cnt 3)
(sub (add1 cnt) (cons n lst))
(sub cnt lst))))
(sub 0 '()))
I am working with a score in Lilypond that has a lot of repetitions, where basically every bar has to be repeated a certain number of times. I would like to be able to write above every bar the number of times it should be repeat, similar to the score below (which was not created in Lilypond):
It would be great to be able to have some brackets above the bar and also to have the "3x" centralized, just like in the example above. So far, the only (temporary) solution I was able to come up with in Lilypond was to add repeat bars and then simply write "3x" above the first note of every bar (since I could not have it centralized on the bar either). It does not look very good, but gets the job done. This temporary solution looks like this:
Any suggestions of how to make this example look more similar to the first inn Lilypond would be extremely welcome!
This is a workaround for this problem:
\version "2.19.15"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% COPY ALL THIS BELOW %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% repeatBracket snippet
% will add .----Nx----. above a bar, where N is the number of repetitions
% based on the wonderful spanner by David Nalesnik (see: http://lists.gnu.org/archive/html/lilypond-user/2014-10/msg00446.html )
#(define (test-stencil grob text)
(let* ((orig (ly:grob-original grob))
(siblings (ly:spanner-broken-into orig)) ; have we been split?
(refp (ly:grob-system grob))
(left-bound (ly:spanner-bound grob LEFT))
(right-bound (ly:spanner-bound grob RIGHT))
(elts-L (ly:grob-array->list (ly:grob-object left-bound 'elements)))
(elts-R (ly:grob-array->list (ly:grob-object right-bound 'elements)))
(break-alignment-L
(filter
(lambda (elt) (grob::has-interface elt 'break-alignment-interface))
elts-L))
(break-alignment-R
(filter
(lambda (elt) (grob::has-interface elt 'break-alignment-interface))
elts-R))
(break-alignment-L-ext (ly:grob-extent (car break-alignment-L) refp X))
(break-alignment-R-ext (ly:grob-extent (car break-alignment-R) refp X))
(num
(markup text))
(num
(if (or (null? siblings)
(eq? grob (car siblings)))
num
(make-parenthesize-markup num)))
(num (grob-interpret-markup grob num))
(num-stil-ext-X (ly:stencil-extent num X))
(num-stil-ext-Y (ly:stencil-extent num Y))
(num (ly:stencil-aligned-to num X CENTER))
(num
(ly:stencil-translate-axis
num
(+ (interval-length break-alignment-L-ext)
(* 0.5
(- (car break-alignment-R-ext)
(cdr break-alignment-L-ext))))
X))
(bracket-L
(markup
#:path
0.1 ; line-thickness
`((moveto 0.5 ,(* 0.5 (interval-length num-stil-ext-Y)))
(lineto ,(* 0.5
(- (car break-alignment-R-ext)
(cdr break-alignment-L-ext)
(interval-length num-stil-ext-X)))
,(* 0.5 (interval-length num-stil-ext-Y)))
(closepath)
(rlineto 0.0
,(if (or (null? siblings) (eq? grob (car siblings)))
-1.0 0.0)))))
(bracket-R
(markup
#:path
0.1
`((moveto ,(* 0.5
(- (car break-alignment-R-ext)
(cdr break-alignment-L-ext)
(interval-length num-stil-ext-X)))
,(* 0.5 (interval-length num-stil-ext-Y)))
(lineto 0.5
,(* 0.5 (interval-length num-stil-ext-Y)))
(closepath)
(rlineto 0.0
,(if (or (null? siblings) (eq? grob (last siblings)))
-1.0 0.0)))))
(bracket-L (grob-interpret-markup grob bracket-L))
(bracket-R (grob-interpret-markup grob bracket-R))
(num (ly:stencil-combine-at-edge num X LEFT bracket-L 0.4))
(num (ly:stencil-combine-at-edge num X RIGHT bracket-R 0.4)))
num))
#(define-public (Measure_attached_spanner_engraver context)
(let ((span '())
(finished '())
(event-start '())
(event-stop '()))
(make-engraver
(listeners ((measure-counter-event engraver event)
(if (= START (ly:event-property event 'span-direction))
(set! event-start event)
(set! event-stop event))))
((process-music trans)
(if (ly:stream-event? event-stop)
(if (null? span)
(ly:warning "You're trying to end a measure-attached spanner but you haven't started one.")
(begin (set! finished span)
(ly:engraver-announce-end-grob trans finished event-start)
(set! span '())
(set! event-stop '()))))
(if (ly:stream-event? event-start)
(begin (set! span (ly:engraver-make-grob trans 'MeasureCounter event-start))
(set! event-start '()))))
((stop-translation-timestep trans)
(if (and (ly:spanner? span)
(null? (ly:spanner-bound span LEFT))
(moment<=? (ly:context-property context 'measurePosition) ZERO-MOMENT))
(ly:spanner-set-bound! span LEFT
(ly:context-property context 'currentCommandColumn)))
(if (and (ly:spanner? finished)
(moment<=? (ly:context-property context 'measurePosition) ZERO-MOMENT))
(begin
(if (null? (ly:spanner-bound finished RIGHT))
(ly:spanner-set-bound! finished RIGHT
(ly:context-property context 'currentCommandColumn)))
(set! finished '())
(set! event-start '())
(set! event-stop '()))))
((finalize trans)
(if (ly:spanner? finished)
(begin
(if (null? (ly:spanner-bound finished RIGHT))
(set! (ly:spanner-bound finished RIGHT)
(ly:context-property context 'currentCommandColumn)))
(set! finished '())))
(if (ly:spanner? span)
(begin
(ly:warning "I think there's a dangling measure-attached spanner :-(")
(ly:grob-suicide! span)
(set! span '())))))))
\layout {
\context {
\Staff
\consists #Measure_attached_spanner_engraver
\override MeasureCounter.font-encoding = #'latin1
\override MeasureCounter.font-size = 0
\override MeasureCounter.outside-staff-padding = 2
\override MeasureCounter.outside-staff-horizontal-padding = #0
}
}
repeatBracket = #(define-music-function
(parser location N note)
(number? ly:music?)
#{
\override Staff.MeasureCounter.stencil =
#(lambda (grob) (test-stencil grob #{ #(string-append(number->string N) "×") #} ))
\startMeasureCount
\repeat volta #N { $note }
\stopMeasureCount
#}
)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ...UNTIL HERE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
{
\repeatBracket 7 {c'1}
\repeatBracket 32 {d' g}
\repeatBracket 14 {e' f g}
\repeatBracket 29 {f' a bes \break cis' e''}
\repeatBracket 1048 {g'1}
}
This code above gives the following result:
]
This solution was not created by myself, but sent to me by David Nalesnik, from lilypond-user mailing list. I just would like to share it here in case someone would need it as well. I've made just some very minor adjustments to what David sent me.
I just had a similar problem but preferred the style on your second example, with the 3x above the bar. The solution I found was:
f e d c |
\mark \markup {"3x"}\repeat volta 3 {c d e f}
f e d c |
generating
Maybe someone else has a use for it.