Have spent lots of time trying to understand syntax-case, yet there are no simple examples. At least until I came across this post.
Small change for Iron Scheme -
(define-syntax is-nil?
(lambda (stx)
(syntax-case stx ()
((_ ()) #t)
((_ stx) #f))))
This is Sid's Blog on Lisp, Scheme and everything in between.
Have spent lots of time trying to understand syntax-case, yet there are no simple examples. At least until I came across this post.
Small change for Iron Scheme -
(define-syntax is-nil?
(lambda (stx)
(syntax-case stx ()
((_ ()) #t)
((_ stx) #f))))
If you were like me and skipped through most of the chapter on quote, quasiquote and splicedquote, then you made a bad mistake. This part is particularily important as the whole macro business is dependent on this. So here's a refresher.
Very simply put quote just quotes its arguments. So, when we execute the following, we get the output as test.
(import (rnrs))
(define foo 'test)
(display foo)
Quasiquote allows us to do more. It allows us have a template which we can fill in with values. Consider the following.
(import (rnrs))
(define x 10)
(display `(list x ,x))
The output will be (list x 10). However, the advantage of quasiquote goes much beyond just templates. We can use it to debug our code better.
Now, we want to understand how fact works. So, let us re-write fact not to compute the value but to just print out the expanded s-expressions.
(import (rnrs))
(define (fact n)
(cond
((or (= n 0) (= n 1)) n)
(else (* n (fact (- n 1))))))
(display (fact 5))
(import (rnrs))
(define (fact n)
(cond
((or (= n 0) (= n 1)) n)
(else `(* ,n ,(fact (- n 1))))))
(display (fact 5))
Now the output is more interesting - (* 5 (* 4 (* 3 (* 2 1)))). What quasiquote and unquote ended up showing us is how the expression is calculated. Now, the fact example is trivial but it does give us an insight into the computation involved.
Related to quote is spliced-quote. If we use spliced-quote then the output of a list is expanded. So,
(import (rnrs))
(define foo `(1 ,@(list 2 3)))
(define bar `(1 (list 2 3)))
(display foo)
(newline)
(display bar)
(newline)
will give us the output as (1 2 3) and (1 (list 2 3)).
What does that mean? It means you create a macro that is lexically
bound. That means, let-syntax acts just like let, but it works on
syntax rather than variables. This means we can use let-syntax to
create localized macros. Consider this example..
(import (rnrs))
(define (hw n)
(display n)
(newline))
(let-syntax ((hw
(syntax-rules ()
((_ 0) (begin
(display "Hello World")
(newline)))
((_ n) (begin
(display "Goodbye World")
(newline))))))
(begin
(hw 0)
(hw 1)))
(hw 0)
(hw 1)
The (hw 0) and (hw 1) inside let-syntax end up printing "Hello World"
and "Goodbye World", whereas the (hw 0) and (hw 1) outside the scope,
print 0 and 1.
(import
(rnrs)
(ironscheme clr)
(ironscheme clr shorthand))
(clr-reference System.Windows.Forms)
(clr-reference System.Drawing)
(clr-using System.Windows.Forms)
(clr-using System.Drawing)
;; Macros
;; Macro to set a property
(define-syntax set-property!
(syntax-rules (:button :form)
((set-property! :button button text x y)
(let ((b button))
(with-clr-type ((b Button))
(b : Text = text)
(b : Location = (clr-new Point x y)))))
((set-property! :form form text)
(let ((f form))
(with-clr-type ((f Form))
(f : Text = text))))))
;; Main Function that runs the form
(define (run form controls b1 b2)
(let ((mc controls))
(begin
(with-clr-type ((mc Form+ControlCollection))
(mc : Add (b1))
(mc : Add (b2))))
;; SHOW FORM AND RUN PUMP
(clr-static-call System.Console WriteLine "Start")
(clr-static-call Application (Run Form) form)
(clr-static-call System.Console WriteLine "Stop")
;; REMOVE CONTROLS
(with-clr-type ((mc Form+ControlCollection))
(mc : Remove (b1))
(mc : Remove (b2)))))
;; SETUP EVENTS
(define (make-event-handler text)
(lambda (s e)
(display text)
(newline)))
(define mainForm_MouseEnter (make-event-handler "Enter"))
(define mainForm_MouseLeave (make-event-handler "Leave"))
(define btnGo_Click (make-event-handler "Go"))
(define btnStop_Click (make-event-handler "Stop"))
(begin
;; INITIALIZE
(define mainForm (clr-new Form))
(define btnGo (clr-new Button))
(define btnStop (clr-new Button))
(define mainControls (clr-prop-get Form Controls mainForm))
;; APPLY EVENTS
(clr-event-add! Form MouseEnter mainForm mainForm_MouseEnter)
(clr-event-add! Form MouseLeave mainForm mainForm_MouseLeave)
(clr-event-add! Button Click btnGo btnGo_Click)
(clr-event-add! Button Click btnStop btnStop_Click)
(set-property! :form mainForm "Hello World")
(set-property! :button btnGo "GO" 10 20)
(set-property! :button btnStop "STOP" 100 20)
(run mainForm mainControls btnGo btnStop)
;; REMOVE EVENTS
(clr-event-remove! Form MouseEnter mainForm mainForm_MouseEnter)
(clr-event-remove! Form MouseLeave mainForm mainForm_MouseLeave)
(clr-event-remove! Button Click btnGo btnGo_Click)
(clr-event-remove! Button Click btnStop btnStop_Click))
# Generate a nice changelog from git
PREV=
for I in `git tag`; do
echo " ";
git log --pretty=format:" %s" $PREV..$I;
echo " ";
echo $I;
PREV=$I;
done | tac > CHANGELOG
Started implementing my own stack based language. I have played a bit with factor and liked it, so I decided to base some things from it. I also have started to read a little more on forth and have now understood how some basic constructs can be created. Especially useful is jonesforth. The code is a must read!
So, the design goals I have in mind are as follows.
So far, I have the basic language working. It supports numbers, strings and quotations. You can define your own "words" and run them. There is a "if" control structure and a "loop" control structure. The implementation is still very buggy though.
Will keep posting as I progress.
( scratchpad ) "ಕನ್ನಧ"--- Data stack:"ಕನ್ನಧ"( scratchpad ) dup--- Data stack:"ಕನ್ನಧ""ಕನ್ನಧ"( scratchpad ) reverse dup reverse--- Data stack:"ಕನ್ನಧ""ಧನ್ನಕ""ಕನ್ನಧ"( scratchpad ) drop--- Data stack:"ಕನ್ನಧ""ಧನ್ನಕ"
( scratchpad ) "ಸಿದ್ದಾರ್ಥ"--- Data stack:"ಸಿದ್ದಾರ್ಥ"( scratchpad ) dup reverse--- Data stack:"ಸಿದ್ದಾರ್ಥ""ಥ್ರಾದ್ದಿಸ"( scratchpad )
Does Factor support Unicode?There is no one meaning to the phrase "Unicode support", but there are a few things that a modern programming language is expected to support in its library: UTF-8/UTF-16 input and output, Unicode collation, Unicode-appropriate casing operations, normalization, strings can hold any Unicode code point, and support for Unicode text rendering in the UI. Of these, Factor supports all but Unicode font rendering, which should be finished before 1.0 comes out.How do I convert a character to upper or lower case in Unicode?This isn't a well-defined operation. For example, the ß character becomes SS in upper case. Some letters have context-dependent case mappings. So if you need to change the case of something, use strings, not individual characters. The Factor Unicode library doesn't implement character mapping, because the behavior could only be incorrect. If what you're converting is just ASCII, then there are character conversion routines defined just for that. For case-insensitive comparison, partial collation keys might be appropriate.
stack(S) ->
io:format("Stack:~p~n", [S]),
receive
{push, PID, Data} ->
PID ! success,
stack([Data|S]);
{pop, PID} ->
if
S == [] ->
PID ! failed,
stack(S);
true ->
[H|T] = S,
PID ! {success, H},
stack(T)
end
end.