I call B.S. on the Oslo “M” Language


There was alot of hype around the new Oslo “M” language during the PDC.
It was pretty much explained as a new way to let people create their own domain specific languages.

Since I have a bit of fetish for parsing and DSL’s I attended to the “M Grammar” presentation.

They began by explaining that “M” is so easy that everyone and his mother will now be able to create their own DSL.
And ofcourse they had to show some trivial example that actually wasn’t a DSL at all, but merely a data transformer that transformed a textual list of “contacts” into a structured list.

Maybe I’m just stupid, but when I hear “new” and “easy” I don’t really associate that with old-school LEX and YACC BNF grammars.
But MS apparently do.

Just check this out, this is a small snippet of M Grammar definition of the language itself:

  syntax CompilationUnit
       = decls:ModuleDeclaration*
         =>
           id("Microsoft.M.CompilationUnit")
           {
               Modules { decls }
           };
  
  
   syntax ExportDirective
       = "export" members:ParsedIdentifiers ";"
         =>
         id("Microsoft.M.ExportDirective")
         {
             Names { members }
         };  
  
   syntax ImportAlias
       = "as" alias:ParsedIdentifier
         => alias;
   
   syntax ImportDirective
       = "import" imports:ImportModules ";"
         =>
         id("Microsoft.M.ModuleImportDirective")
         {
             Modules { imports }
         }
                 | "import" targetModule:MemberAccessExpression "{" members:ImportMembers "}" ";"
           =>
           id("Microsoft.M.MemberImportDirective")
           {
               ModuleName { targetModule },
               Members { members }
           };
   
   syntax ImportMember
       = member:ParsedIdentifier alias:ImportAlias?
           => id("Microsoft.M.ImportedName")
           {
               Name { member },
               Alias { alias }
           };

The grammars in “M” was essentially a hybrid of old BNF definitions mixed up with functional programming elements.

I’m not saying that their approach was bad, just that it wasn’t really as easy as they wanted it to be.
There are a few gems in it, but it does in no way lower the compexity of defining a grammar in such a way that everyone will be able to create real DSL’s.

Maybe some people will create a few data transformers using this approach, but I don’t expect to see more “real” DSL’s popping up now than we have seen before..

//Roger

Caramel – Alpha source code is public


I have added the Caramel code generator to my public repository at google code.
http://code.google.com/p/alsing/

Please note that this is very very alpha and not actually useful yet.

Before it can be used I need to finish the template support and fully implement the DB meta data importer.

But if you are interested in this kind of stuff and want to help out building it, please let me know.

DSLisp


MyLisp is now named DSLisp – Domain Specific (Language) Lisp.

I have published it as a project on CodePlex:
http://www.codeplex.com/DSLisp

The new name imples the purpose of the project.
To act as a host for DSL’s.

The idea is to compile your DSL into the DSLisp AST.
And then run your DSL inside the DSLisp engine.
By doing this you can very easily add single step debugging and breakpoint support to your DSL. 

See the codeplex site for more info.

Lisp Debugger


I’m still working on my Lisp language clone.
Today I started to add debugging support to it.
I made the AST aware of the original source code, so each node can reference back to the place it was parsed from, and I also added a bit of call stack features.

I’m pretty satisfied with it so far, it almost feels like a real language now ;-)

Anyway, here is a screenshot of the not so well designed GUI.

 Debugger
Click for full size.

Downloads are available at: 

Source: http://www.puzzleframework.com/roger/mylisp.zip
Binaries: http://www.puzzleframework.com/roger/mylispbin.zip

(The code is written in C#3, VS.NET 2008 solution)

Lisp weekend


I’ve been reading up a bit on functional programming the last few week, the reason is just to comprehend the new features and possibilities in .NET 3.5 as much as possible.

Anyway, I got a bit carried away and started to read about Lisp, and decided to learn what it’s all about.
So what better way to learn a language than to make your own parser for it is there? ;-)

I started to hammer away on a simple parser, and once the parser was done, I couldn’t stop, so I began writing an engine too.
So after a few hours of Aha moments, I finally got my very own Lisp(ish) code executor and a bit more understanding for the language. ;-)

Well, enough blabbering, here are a few samples of whats currently possible in my still un-named language.

Hello world:

(print 'Hello world!')

Simple function and call:

(defun Mul (x y) 
 (* x y))       

(print (Mul 2 3))

Variables:

(let my-var 'hello lisp') 
(let my-int 123) 
(let my-double 123.456) 
(let half-pi (/ pi 2)) 
(let my-arr (arr 1 2 3 4 5 6 7))

Loops:

(foreach item my-arr 
 (print item))      

(for i 1 20 
 (print i))      

(let i 0) 
(while (< i 20) 
 ((print i) (++ i)))

Lambdas:

(let my-lambda (lambda (x y) (* x y))) 
(my-lambda 2 3)

Delegates:

(let my-delegate Mul) // delegate to Mul 
(let print other-print-func) //redirect the print function to "other-print-func"

Objects:

(let form (new Form)) 
(set form Text 'hello windows forms') 
(let button (new Button)) 
(set button Text 'my button') 
(set-event button Click MyButtonClick) 
(list-add (get form Controls) button) 
(call form Show)

List comprehensions:

(foreach item (select (lambda (concat 'transformed: ' item '!')) 
              (where (lambda (> (get item Length) 3)) 
              (list 'foo' 'bar' 'roger' '.net' 'lisp')))       

      (print item))

The next step will be to make it possible to define your own classes.
Im thinking of emitting true .NET classes and let the methods redirect the calls to the engine.
Thus making it possible to redefine the behaviour of a method in runtime.

That, and find some reason to use it :-P

Query Objects vs. DSL


 THIS IS AN OLD POST FROM MY OLD BLOG (2006)

 Most O/R Mappers today support some sort of Query Objects.
Query Objects are often some sort of semi fluent combination of objects and methods where you can build a query.
 
Query objects also seem to be the preferred way to build queries in code because they are “Typed”.
Being “Typed” comes with two major benefits, you get intellisense (to some extent) and you get compiler warnings if you do something way too funky with your query.
 
When Mats Helander started to build NPersist, he went for a DSL approach instead of QO’s and invented NPath which object query language similar to SQL in syntax.
 
So why go for an untyped DSL instead of typed QO?
 
Well, one thing that QO’s does not do is to verify your logic, you need unit tests for that.
And once you’ve got unit tests, the benefit of being strictly typed is reduced because with unit tests you can clearly see if your untyped code does work or not.
 
QO’s still got the benefit of intellisense,
But let’s look at the readability of two queries:
 
(the queries come from : http://www.mygenerationsoftware.com/phpbb2/viewtopic.php?t=107)
 
SQL:

SELECT * FROM Employees 
WHERE LastName LIKE 'A%' AND LastName IS NOT NULL OR 
( City LIKE 'Ind%' OR HireDate BETWEEN '1/1/95' AND '4/4/04' )

[edit: added npath sample]

NPath:

SELECT * FROM Employee 
WHERE LastName LIKE 'A%' AND LastName != NULL OR 
( City LIKE 'Ind%' OR HireDate BETWEEN #1/1/95# AND #4/4/04# )

NOTE: npath specifies classes and properties , not tables and fields
See: *** Missing Page *** : Old blog is gone
[/edit]
 

dOOdas ORM:

Dim emps As Employees = New Employees 
emps.Where.LastName.Value = "A%" 
emps.Where.LastName.Operator = WhereParameter.Operand.Like 
Dim wp As WhereParameter = emps.Where.TearOff.LastName 
wp.Operator = WhereParameter.Operand.IsNotNull 
emps.Query.AddConjunction WhereParameter.Conj.Or 
emps.Query.OpenParenthesis() 
emps.Where.City.Conjuction = WhereParameter.Conj.And 
emps.Where.City.Value = "Ind%" 
emps.Where.City.Operator = WhereParameter.Operand.Like 
emps.Where.HireDate.Conjuction = WhereParameter.Conj.Or 
emps.Where.HireDate.Operator = WhereParameter.Operand.Between 
emps.Where.HireDate.BetweenBeginValue = "1/1/95" 
emps.Where.HireDate.BetweenEndValue = "4/4/04" 
emps.Query.CloseParenthesis()

Are QO’s really sane?
If the whole purpose of an O/R Mapper is to reduce code and enable RAD, shouldn’t it be easier to query your DB?
I was a LLBL gen pro user a few years ago and loved most parts of it, but I just couldn’t stand the QO’s.
Just making a query with a few conditions and some sorting would generate queries similar to the one above.
Even if Frans has excellent documentation and the classes got intellisense and all, I still had to spend way too much time
just to make a simple query that should take a few seconds to write.
(I have to add that I haven’t looked at LLBL Gen since and Frans might have altered the API or added some DSL, I’m just stating what I experienced with it about 2 years ago.
my arguments are also targeted against QO’s in general, not only the ones in LLBL Gen)

Later on I got in contact with Mats and saw NPath for the first time, and I loved it, NPath is the #1 reason I teamed up with Mats and started co-develop NPersist.
With NPath I can write queries that are similar to SQL but instead of targeting your DB schema you target your domain classes and properties, and instead of creating joins you just traverse property paths.

So even if NPath is untyped I still find it way more productive than any QO’s and I get a smaller code base which is easy to read and since I do unit tests I can verify that my untyped queries does work as intended.
It would be very interesting to hear other opinions on this topic and why QO’s still is the most common way to make queries in O/R Mappers?
Is it because of the intellisense?
or because most people don’t do unit tests?
or just because it looks cool with some huge object graph?
or because most O/R vendors don’t know how to make a decent parser?

Fire away! :-)

[edit]
Just added this sample incase anyone is interested in NPath and in mem querying:
http://web.archive.org/web/20070103130842/http://blogs.wdevs.com/phirephly/archive/2006/02/03/12096.aspx
[/edit]