Monday, November 30, 2009

The simplest syntax-case

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))))

The importance of quasiquote

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. 



(import (rnrs))

(define (fact n)
(cond
((or (= n 0) (= n 1)) n)
(else (* n (fact (- n 1))))))

(display (fact 5))
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))

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)).

Monday, November 23, 2009

Scheme - let-syntax

It took me some time to understand what let-syntax does. After
spending much time on the net search for information, I finally
figured it out. let-syntax is the let counterpart of define-syntax.

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.

Wednesday, November 18, 2009

Windows Forms in IronScheme

The Discussion thread on Iron Scheme's project is here. I spent some time, playing with the code, and changing the style. Here's what I got.


(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))

Thursday, October 29, 2009

Emacs tramp mode vs. angeftp

Looks like I had it completely wrong!

Emacs tramp mode is really awesome. From windows if we use plink then everything just works, include things like vc-mode, make etc..

Wednesday, October 28, 2009

git-changelog

I like to use git tag to keep track of revision versions in my code. When I do deliver my code, its usually as a prebuilt binary with code, generated documentation and most importantly a CHANGELOG file. What does happen is that the entire .git tree is not shipped. (Hey, if you need the git tree, just pull off it. You don't need a release).

I tried git-log to generate a CHANGELOG but it does not give me a mapping to tags. So, here's a bash script that does that.


# 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


Works like a charm!

The difference between FILE* and FD

Obviously using fopen, fwrite etc... is a little bit easier especially since you don't have to keep track of the location in the stream, using plain old open, write etc.. also have their uses.

Consider this.. I want to write a test case which writes to a file over and over again. The idea is to write x bytes to the file, seek to 0, and repeat.

Problem is that this will not work when you use FILE pointers. It will work most times, except when the file itself has to be created. In which case, using seek to 0 does nothing, because every fwrite will automatically seek to the end of the file. So, fopen a new file will always open it in append mode.

Thursday, October 08, 2009

Its my baby

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.

  1. Must be in embeddable in C. My main goal here is to be like Lua. A small library that you can call from C. The main users of this language would be hardcode C programmers esp. on embedded linux and embedded linux system testers. 
  2. Must be written in ANSI C. Factor implementation has moved to C++ and also has a lot work going on in creating a fast and optimizing VM. I don't have that goal, as I want to be able to port my language very quickly to different hardware. The easiest way to port? Just recompile. Obviously, you lose out on some performance, but that's ok. The target audience will code most of the fast bits in C anyways.
  3. Must be simple. System testers should be able to use this language very quickly to write small tests. The main part of the test application itself would be written in C, but the scripting part would be in this language.
  4. Support for quotations, sequences. Ideas from Factor (and lisp) and good ones too!
  5. Reader macros would primarily be from C. 

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.

Tuesday, September 22, 2009

Factor and Unicode

I'm just starting with Factor. More for fun rather than anything else. Selling it at work will be a real task!

Anyways, I was curious about unicode support.

So, I tried to reverse a kannada word! Here's what I got.

( scratchpad ) "ಕನ್ನಧ"

--- Data stack:
"ಕನ್ನಧ"
( scratchpad ) dup

--- Data stack:
"ಕನ್ನಧ"
"ಕನ್ನಧ"
( scratchpad ) reverse dup reverse

--- Data stack:
"ಕನ್ನಧ"
"ಧನ್ನಕ"
"ಕನ್ನಧ"
( scratchpad ) drop

--- Data stack:
"ಕನ್ನಧ"
"ಧನ್ನಕ"
So far so good. But lets change the vowels!
( scratchpad ) "ಸಿದ್ದಾರ್ಥ"

--- Data stack:
"ಸಿದ್ದಾರ್ಥ"
( scratchpad ) dup reverse

--- Data stack:
"ಸಿದ್ದಾರ್ಥ"
"ಥ್ರಾದ್ದಿಸ"
( scratchpad )
Now, we have a problem! This is part of the FAQ.
Quoting -

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.

Friday, March 13, 2009

Lua is a god send

I have been spending some time integrating Lua with some code. Its really good. Adding Lua scriptability is almost trivial and the payoffs are just amazing.

Worth checking out. Lua homepage.

Friday, March 06, 2009

YASnippet mode - The biggest time saver

If you haven't tried YASnippet with Emacs yet, then do it ASAP. Its awesome.

Its a clone of textmate's snippets feature, but I don't have Mac and haven't seen/used it. YASnippet by itself is awesome!

Monday, November 03, 2008

Trouble with Logs

Interesting Post (via reddit) on logging and difference between logs and traces. Also, if you look below, there is a comment on logging in YAML. Now that really caught my eye. Because if it were JSON (which is essentially a YAML subset), we should be able to parse the log directly using Javascript. Taking it a bit further, if I have a log that is in JSON, then we should be able to create a live-update pretty easily.

Hmmm.. We are looking at some specific formats for logging in our applications. This maybe a good idea.

Technorati Tags: , ,

Sunday, November 02, 2008

The power of clojure is growing

Clojure is a great idea. Take lisp, apply it to the JVM, add functional programming sauces and voila!, you can now do QT programming!

Wednesday, October 29, 2008

More on Latex tables

More issues with latex tables. I don't always agree with the placement algorithm that latex is using for my document. As a result, my tables are often placed away from related content. This is despite me using h! as a specifier. Any options?

Technorati Tags:

Tuesday, October 28, 2008

Latex Tables

Latex makes things easy if you are working on a large document. Plus, since everything is plain text, I can easily diff, merge, patch etc.. In general, I prefer latex to any WYSIWYG word processor, even though I end up running pdflatex quick often on the source.

However,  there is one item that's a real sour point. Tables. Its just not inituitive enough with Latex. Getting a nice spreadsheet view of things is a real plus point with word processors but with latex that just doesn't fly. You can use table and tabular environments, but they are still quick clumsy.

Assuming that you writing your document with emacs, the ideal scenario would be for a combination of org-tbl-mode and auctex. org-tbl-mode is really cool for tabular representation of data but just does not work with tex.

Technorati Tags:

Sunday, October 26, 2008

Uclibc vs. Glibc

I'm not sure about the differences. Lots of embedded linux products seem to use uclibc. The way I understand it, uclibc serves a particular market - embedded linux by cutting down on features that are not required. The question then is what do we lose?

We had to support both glibc and uclibc in a project sometime back. The project is still ongoing, but I seem to have forgotten what were the changes we had to make and test for.

If I have a threaded application, will it compile against uclibc? It will, but I don't know about all the differences. Will keep updating this post with differences as I come across them.

Saturday, October 25, 2008

A Stack in Erlang

I have been playing around with Erlang for a couple of weeks now. Its a really cool language and here's my first attempt at implementing a stack in it.

The basic design is to have process that gets different commands as messages, and updates the stack accordingly. Erlang being a functional language, implies that we cannot use an imperative approach. So, here's what the process looks like.

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.

Its pretty simple actually, but I did have a lot a trouble with push. Each push would create a list within a list, which meant that there could be only 2 pops. However, if we spawn stack with [] as that input parameter, then it works fine.

Next steps -> Get some more stack operations going. I'm going to implement a couple of functions - dup, swap, rot.

Technorati Tags:

A whole new world

This blog is about my thoughts on software, programming, project management etc.. In short, anything that related to my professional interests. What are my interests? I like different programming languages, productivity tools, documentation tools, and in general just coding. Who am I? I'm a software architect in India and this is my blog on technically, anything.