From: Pascal Costanza
Subject: Martin Fowler talks about Lisp...
Date: 
Message-ID: <3ilnm1Fmbko6U1@individual.net>
...and favorably so. See 
http://martinfowler.com/articles/languageWorkbench.html


Pascal

-- 
2nd European Lisp and Scheme Workshop
July 26 - Glasgow, Scotland - co-located with ECOOP 2005
http://lisp-ecoop05.bknr.net/

From: Joe Marshall
Subject: Re: Martin Fowler talks about Lisp...
Date: 
Message-ID: <wtoab5b2.fsf@ccs.neu.edu>
Pascal Costanza <··@p-cos.net> writes:

> ...and favorably so. See
> http://martinfowler.com/articles/languageWorkbench.html

I noticed that Tiobe ( http://www.tiobe.com/ )
now rates Lisp as a `Mainstream Language' with an `A' rating.

What is the world coming to?
From: Andras Simon
Subject: Re: Martin Fowler talks about Lisp...
Date: 
Message-ID: <vcdmzp5ihx5.fsf@csusza.math.bme.hu>
Joe Marshall <···@ccs.neu.edu> writes:

> Pascal Costanza <··@p-cos.net> writes:
> 
> > ...and favorably so. See
> > http://martinfowler.com/articles/languageWorkbench.html
> 
> I noticed that Tiobe ( http://www.tiobe.com/ )
> now rates Lisp as a `Mainstream Language' with an `A' rating.
> 
> What is the world coming to?

Its senses.

Andras
From: ··············@hotmail.com
Subject: Re: Martin Fowler talks about Lisp...
Date: 
Message-ID: <1121776108.882854.117790@o13g2000cwo.googlegroups.com>
Joe Marshall wrote:
> Pascal Costanza <··@p-cos.net> writes:
>
> > ...and favorably so. See
> > http://martinfowler.com/articles/languageWorkbench.html
>
> I noticed that Tiobe ( http://www.tiobe.com/ )
> now rates Lisp as a `Mainstream Language' with an `A' rating.
>
It brings you just below ECMAScript  :)
http://www.itjobswatch.co.uk/default.aspx?page=2&sortby=0&orderby=0&jt=0&q=&id=900

The mainstream languages  are on the other page :
1 SQL
2 Java
3 C++
4 VB
5 Perl
........
http://www.itjobswatch.co.uk/default.aspx?page=1&sortby=0&orderby=0&jt=0&q=&id=900
From: Rainer Joswig
Subject: Re: Martin Fowler talks about Lisp...
Date: 
Message-ID: <BEEB939B.EEF4%joswig@lisp.de>
Am 01.07.2005 22:34 Uhr schrieb "Pascal Costanza" unter <··@p-cos.net> in
··············@individual.net:

> ...and favorably so. See
> 
> http://martinfowler.com/articles/languageWorkbench.html
> 
> 
> Pascal


His example in some primitive way:


The macro does most of the work. It generates a class for
the data and two methods for parsing the lines.


(defmacro defmapping (name mapping &body fields)
  `(progn
     (defclass ,name ()
       ,(loop for (nil nil slot) in fields
              collect slot))
     (defmethod find-mapping-class-name ((mapping (eql ',(intern mapping))))
       ',name)
     (defmethod parse-line-for-class (line (class-name (eql ',(intern
name))))
       (let ((object (make-instance class-name)))
         (loop for (start end slot) in ',fields
               do (setf (slot-value object slot) (subseq line start (1+
end))))
         object))))



Now we use the macro to define the mappings:


(defmapping service-call "SVCL"
  (04 18 customer-name)
  (19 23 customer-id)
  (24 27 call-type-code)
  (28 35 date-of-call-string)))

(defmapping usage "USGE"
  (04 08 customer-id)
  (09 22 customer-name)
  (30 30 cycle)
  (31 36 read-date))


The example lines:

(defparameter *test-lines*
"SVCLFOWLER         10101MS0120050313.........................
SVCLHOHPE          10201DX0320050315........................
SVCLTWO           x10301MRP220050329..............................
USGE10301TWO          x50214..7050329...............................")


Let's try it out:


CL-USER 21 > (map nil 'describe
     (with-input-from-string (stream *test-lines*)
       (loop for line = (read-line stream nil nil)
             while line
             collect (parse-line-for-class line (find-mapping-class-name
(intern (subseq line 0 4)))))))

#<SERVICE-CALL 10082C7F> is a SERVICE-CALL
CUSTOMER-NAME            "FOWLER         "
CUSTOMER-ID              "10101"
CALL-TYPE-CODE           "MS01"
DATE-OF-CALL-STRING      "20050313"
#<SERVICE-CALL 100828A3> is a SERVICE-CALL
CUSTOMER-NAME            "HOHPE          "
CUSTOMER-ID              "10201"
CALL-TYPE-CODE           "DX03"
DATE-OF-CALL-STRING      "20050315"
#<SERVICE-CALL 100824BB> is a SERVICE-CALL
CUSTOMER-NAME            "TWO           x"
CUSTOMER-ID              "10301"
CALL-TYPE-CODE           "MRP2"
DATE-OF-CALL-STRING      "20050329"
#<USAGE 100820CF> is an USAGE
CUSTOMER-ID        "10301"
CUSTOMER-NAME      "TWO          x"
CYCLE              "7"
READ-DATE          "050329"
From: ·········@gmail.com
Subject: Re: Martin Fowler talks about Lisp...
Date: 
Message-ID: <1120682504.831133.48350@g47g2000cwa.googlegroups.com>
Rainer Joswig wrote:
> (defmacro defmapping (name mapping &body fields)
>   `(progn
>      (defclass ,name ()
>        ,(loop for (nil nil slot) in fields
>               collect slot))
>      (defmethod find-mapping-class-name ((mapping (eql ',(intern mapping))))
>        ',name)
>      (defmethod parse-line-for-class (line (class-name (eql ',(intern
> name))))
>        (let ((object (make-instance class-name)))
>          (loop for (start end slot) in ',fields
>                do (setf (slot-value object slot) (subseq line start (1+
> end))))
>          object))))

Hi Rainer!

This was very interesting. How short and simple you made it look,
especially compared to that clumsy C# code Martin posted. However, I
tried your code on both clisp and sbcl and ran into a problem. (intern
'something) doesn't work in them so I had to change your code a tiny
bit.

Here's a version that works for me. Please let me know if the fix is
insufficient in some way,

(defmacro defmapping (name mapping &body fields)
  `(progn
     (defclass ,name ()
       ,(loop for (nil nil slot) in fields
	   collect slot))
     (defmethod find-mapping-class-name ((mapping (eql ',(intern
mapping))))
       ',name)
     (defmethod parse-line-for-class (line (class-name (eql ',(intern
							       (symbol-name name)))))
       (let ((object (make-instance class-name)))
         (loop for (start end slot) in ',fields
	    do (setf (slot-value object slot) (subseq line start (1+
								  end)))) 
         object)))) 

Regards, Tommy
From: Rainer Joswig
Subject: Re: Martin Fowler talks about Lisp...
Date: 
Message-ID: <BEF306B6.FE68%joswig@lisp.de>
Am 06.07.2005 22:41 Uhr schrieb ··········@gmail.com" unter
<·········@gmail.com> in
·······················@g47g2000cwa.googlegroups.com:

> Rainer Joswig wrote:
>> (defmacro defmapping (name mapping &body fields)
>>   `(progn
>>      (defclass ,name ()
>>        ,(loop for (nil nil slot) in fields
>>               collect slot))
>>      (defmethod find-mapping-class-name ((mapping (eql ',(intern mapping))))
>>        ',name)
>>      (defmethod parse-line-for-class (line (class-name (eql ',(intern
>> name))))
>>        (let ((object (make-instance class-name)))
>>          (loop for (start end slot) in ',fields
>>                do (setf (slot-value object slot) (subseq line start (1+
>> end))))
>>          object))))
> 
> Hi Rainer!
> 
> This was very interesting. How short and simple you made it look,
> especially compared to that clumsy C# code Martin posted. However, I
> tried your code on both clisp and sbcl and ran into a problem. (intern
> 'something) doesn't work in them so I had to change your code a tiny
> bit.
> 
> Here's a version that works for me. Please let me know if the fix is
> insufficient in some way,
> 
> (defmacro defmapping (name mapping &body fields)
>   `(progn
>      (defclass ,name ()
>        ,(loop for (nil nil slot) in fields
>   collect slot))
>      (defmethod find-mapping-class-name ((mapping (eql ',(intern
> mapping))))
>        ',name)
>      (defmethod parse-line-for-class (line (class-name (eql ',(intern
>       (symbol-name name)))))
>        (let ((object (make-instance class-name)))
>          (loop for (start end slot) in ',fields
>    do (setf (slot-value object slot) (subseq line start (1+
>  end)))) 
>          object))))
> 
> Regards, Tommy
> 

Try this one:

(defmacro defmapping (name mapping &body fields)
  `(progn
     (defclass ,name ()
       ,(loop for (nil nil slot) in fields
              collect slot))
     (defmethod find-mapping-class-name ((mapping (eql ',(intern mapping))))
       ',name)
     (defmethod parse-line-for-class (line (class-name (eql ',name)))
       (let ((object (make-instance class-name)))
         (loop for (start end slot) in ',fields
               do (setf (slot-value object slot)
                        (subseq line start (1+ end))))
         object))))
From: Rainer Joswig
Subject: Re: Martin Fowler talks about Lisp...
Date: 
Message-ID: <BEF3877D.FF7F%joswig@lisp.de>
Am 07.07.2005 16:20 Uhr schrieb "Rainer Joswig" unter <······@lisp.de> in
····················@lisp.de:

> Am 06.07.2005 22:41 Uhr schrieb ··········@gmail.com" unter
> <·········@gmail.com> in
> ·······················@g47g2000cwa.googlegroups.com:
> 
>> Rainer Joswig wrote:
>>> (defmacro defmapping (name mapping &body fields)
>>>   `(progn
>>>      (defclass ,name ()
>>>        ,(loop for (nil nil slot) in fields
>>>               collect slot))
>>>      (defmethod find-mapping-class-name ((mapping (eql ',(intern mapping))))
>>>        ',name)
>>>      (defmethod parse-line-for-class (line (class-name (eql ',(intern
>>> name))))
>>>        (let ((object (make-instance class-name)))
>>>          (loop for (start end slot) in ',fields
>>>                do (setf (slot-value object slot) (subseq line start (1+
>>> end))))
>>>          object))))
>> 
>> Hi Rainer!
>> 
>> This was very interesting. How short and simple you made it look,
>> especially compared to that clumsy C# code Martin posted.

I've written a short article about some DSL style programming technique:

http://lispm.dyndns.org/news?ID=NEWS-2005-07-08-1

> However, I
>> tried your code on both clisp and sbcl and ran into a problem. (intern
>> 'something) doesn't work in them so I had to change your code a tiny
>> bit.
>> 
>> Here's a version that works for me. Please let me know if the fix is
>> insufficient in some way,
>> 
>> (defmacro defmapping (name mapping &body fields)
>>   `(progn
>>      (defclass ,name ()
>>        ,(loop for (nil nil slot) in fields
>>   collect slot))
>>      (defmethod find-mapping-class-name ((mapping (eql ',(intern
>> mapping))))
>>        ',name)
>>      (defmethod parse-line-for-class (line (class-name (eql ',(intern
>>       (symbol-name name)))))
>>        (let ((object (make-instance class-name)))
>>          (loop for (start end slot) in ',fields
>>    do (setf (slot-value object slot) (subseq line start (1+
>>  end)))) 
>>          object))))
>> 
>> Regards, Tommy
>> 
> 
> Try this one:
> 
> (defmacro defmapping (name mapping &body fields)
>   `(progn
>      (defclass ,name ()
>        ,(loop for (nil nil slot) in fields
>               collect slot))
>      (defmethod find-mapping-class-name ((mapping (eql ',(intern mapping))))
>        ',name)
>      (defmethod parse-line-for-class (line (class-name (eql ',name)))
>        (let ((object (make-instance class-name)))
>          (loop for (start end slot) in ',fields
>                do (setf (slot-value object slot)
>                         (subseq line start (1+ end))))
>          object))))
> 
> 
From: GP lisper
Subject: Re: Martin Fowler talks about Lisp...
Date: 
Message-ID: <1120863635.4cb311645ca9886eb8604a246f0fd4eb@teranews>
On Fri, 08 Jul 2005 01:29:33 +0200, <······@lisp.de> wrote:
>
> I've written a short article about some DSL style programming technique:
>
> http://lispm.dyndns.org/news?ID=NEWS-2005-07-08-1

I enjoyed the article, but the part that I really need to grok is
looking at:

SVCLHOHPE          10201DX0320050315........................

and seeing a mapping macro as the way to solve this problem.  Clearly
I need to slough thru these problems a few times more.
From: Rainer Joswig
Subject: Re: Martin Fowler talks about Lisp...
Date: 
Message-ID: <BEF54177.10167%joswig@lisp.de>
Am 09.07.2005 0:59 Uhr schrieb "GP lisper" unter <········@CloudDancer.com>
in ···········································@teranews:

> On Fri, 08 Jul 2005 01:29:33 +0200, <······@lisp.de> wrote:
>> 
>> I've written a short article about some DSL style programming technique:
>> 
>> http://lispm.dyndns.org/news?ID=NEWS-2005-07-08-1
> 
> I enjoyed the article, but the part that I really need to grok is
> looking at:
> 
> SVCLHOHPE          10201DX0320050315........................
> 
> and seeing a mapping macro as the way to solve this problem.  Clearly
> I need to slough thru these problems a few times more.
> 

What you can know from looking at the data is:

- it is some text based format with one record per line
- there is a tag in front of each line, which gives you the record type
- the record will have several fields
- different records will have different sets of fields
- records are best represented by Common Lisp classes
- fields are best represented by Common Lisp object's slots
- then you need a simple way to describe the layout the data and compute the
class from this description
- plus you need some mechanism to get from the record type the class
- ...

Parts of the development process are demonstrated in the video referenced
in the article. You might need some time to download it...
From: GP lisper
Subject: Re: Martin Fowler talks about Lisp...
Date: 
Message-ID: <1120893304.d5c5bf1a459fc4454a4a4c5331821d1d@teranews>
On Sat, 09 Jul 2005 08:55:19 +0200, <······@lisp.de> wrote:
>
> Parts of the development process are demonstrated in the video referenced
> in the article. You might need some time to download it...

If I get it downloaded (second attempt now), I'll rehost it (if you
don't mind).

-- 
LOOP :: a Domain Specific Language.
From: GP lisper
Subject: Re: Martin Fowler talks about Lisp...
Date: 
Message-ID: <1120929324.dea8124342cbd9fba7336ad2d1092175@teranews>
On Sat, 9 Jul 2005 00:14:47 -0700, <········@CloudDancer.com> wrote:
>
>
> On Sat, 09 Jul 2005 08:55:19 +0200, <······@lisp.de> wrote:
>>
>> Parts of the development process are demonstrated in the video referenced
>> in the article. You might need some time to download it...
>
> If I get it downloaded (second attempt now), I'll rehost it (if you
> don't mind).

I think that the resource and data forks (if Macs still do such) are a
problem.  I keep ending up with 125M transferred, but only a 7M file.


-- 
LOOP :: a Domain Specific Language.
From: Rainer Joswig
Subject: Re: Martin Fowler talks about Lisp...
Date: 
Message-ID: <joswig-747818.20563309072005@news-europe.giganews.com>
In article <···········································@teranews>,
 GP lisper <········@CloudDancer.com> wrote:

> On Sat, 9 Jul 2005 00:14:47 -0700, <········@CloudDancer.com> wrote:
> >
> >
> > On Sat, 09 Jul 2005 08:55:19 +0200, <······@lisp.de> wrote:
> >>
> >> Parts of the development process are demonstrated in the video referenced
> >> in the article. You might need some time to download it...
> >
> > If I get it downloaded (second attempt now), I'll rehost it (if you
> > don't mind).
> 
> I think that the resource and data forks (if Macs still do such) are a
> problem.  I keep ending up with 125M transferred, but only a 7M file.

The file has a size of 131323719 bytes. It transfers fine for me.
From: GP lisper
Subject: Re: Martin Fowler talks about Lisp...
Date: 
Message-ID: <1120980605.177b054e4b38384f03e606cb754c8418@teranews>
On Sat, 09 Jul 2005 20:56:33 +0200, <······@lisp.de> wrote:
>
>
> In article <···········································@teranews>,
>  GP lisper <········@CloudDancer.com> wrote:
>
>> On Sat, 9 Jul 2005 00:14:47 -0700, <········@CloudDancer.com> wrote:
>> >
>> >
>> > On Sat, 09 Jul 2005 08:55:19 +0200, <······@lisp.de> wrote:
>> >>
>> >> Parts of the development process are demonstrated in the video referenced
>> >> in the article. You might need some time to download it...
>> >
>> > If I get it downloaded (second attempt now), I'll rehost it (if you
>> > don't mind).
>> 
>> I think that the resource and data forks (if Macs still do such) are a
>> problem.  I keep ending up with 125M transferred, but only a 7M file.
>
> The file has a size of 131323719 bytes. It transfers fine for me.

From mac to mac?  Mac to PC linux?  mac to win32?  Remote or local?


-- 
LOOP :: a Domain Specific Language.
From: GP lisper
Subject: Re: Martin Fowler talks about Lisp...
Date: 
Message-ID: <1120896005.37bfd2c330c160f71ad846e7b79f293a@teranews>
On Sat, 09 Jul 2005 08:55:19 +0200, <······@lisp.de> wrote:
>
> Am 09.07.2005 0:59 Uhr schrieb "GP lisper" unter <········@CloudDancer.com>
> in ···········································@teranews:
>> 
>> SVCLHOHPE          10201DX0320050315........................
>> 
>> and seeing a mapping macro as the way to solve this problem.  Clearly
>> I need to slough thru these problems a few times more.
>
> What you can know from looking at the data is:
>
> - it is some text based format with one record per line
> - there is a tag in front of each line, which gives you the record type
> - the record will have several fields
> - different records will have different sets of fields
> - records are best represented by Common Lisp classes

Agreed (but that last one moved from below to above during the
rewriting of this post).

> - fields are best represented by Common Lisp object's slots
> - then you need a simple way to describe the layout the data and compute the
> class from this description
> - plus you need some mechanism to get from the record type the class

I have Keenes book and several examples, including nifty cells code
from Kenny which follows the above list nearly verbatim.  In writing
this post and rethinking the problem, I get a glimmer of this CLOS
stuff, just as I did when I read Keene the first time.  As an old
assembly hacker, I think I'm so used to writing all the boilerplate
that it is hard to step back from it to see the 'simpler'
approach...but I think I can learn to like CLOS.

Thanks!


-- 
LOOP :: a Domain Specific Language.
From: Joerg Hoehle
Subject: Re: Martin Fowler talks about Lisp...
Date: 
Message-ID: <uvf38i28l.fsf@users.sourceforge.net>
Rainer Joswig <······@lisp.de> writes:
> > SVCLHOHPE          10201DX0320050315........................
> What you can know from looking at the data is:
> - it is some text based format with one record per line
> - there is a tag in front of each line, which gives you the record type
> - the record will have several fields
> - different records will have different sets of fields
Agree with all the above

> - records are best represented by Common Lisp classes
> - fields are best represented by Common Lisp object's slots
This is a bogus conclusion. It doesn't logically follow from anything,
except maybe personal preference.

In one of several such applications, it would have been much to costly
to instanciate a new object for every line (hundreds of thousands, if
not millions of lines in plenty of files).

Instead, I had people write code like when using WITH SLOTS.
They wrote the (vitual) slot names they needed, and that got
transformed (via the DSL) into something like
(parse-integer huge-array :start start-of-that-column :end end-of-that-column)
or even
(let (slotx (parse-integer ...))
  &body)

All the users need to know is the name SLOTX, which they declared
themselves via the DSL that describes each line. The rest was MACRO
and LAMBDA.

In the most recent such application, I made use of CLOS because it has
a nice declarative touch) for configuration only. At the time each
line is processed, nothing was using CLOS anymore. FUNCALL was it.

Regards,
	Jorg Hohle
Telekom/T-Systems Technology Center
From: Rainer Joswig
Subject: Re: Martin Fowler talks about Lisp...
Date: 
Message-ID: <joswig-C42ADD.21050718072005@news-europe.giganews.com>
In article <·············@users.sourceforge.net>,
 Joerg Hoehle <······@users.sourceforge.net> wrote:

> Rainer Joswig <······@lisp.de> writes:
> > > SVCLHOHPE          10201DX0320050315........................
> > What you can know from looking at the data is:
> > - it is some text based format with one record per line
> > - there is a tag in front of each line, which gives you the record type
> > - the record will have several fields
> > - different records will have different sets of fields
> Agree with all the above
> 
> > - records are best represented by Common Lisp classes
> > - fields are best represented by Common Lisp object's slots
> This is a bogus conclusion. It doesn't logically follow from anything,
> except maybe personal preference.

No, if you really want to represent fields and records
(as opposed to use the line and just compute stuff) for
further processing, the usual other options would have
been lists, vectors and structures.

> In one of several such applications, it would have been much to costly
> to instanciate a new object for every line (hundreds of thousands, if
> not millions of lines in plenty of files).

Could be. If you still want to work (temporarily) with objects, there are
a few optimizations. CL-HTTP for example uses pools
(resources) of objects and lazy parsing for the slots.
My applications mostly have been just using pools.

> Instead, I had people write code like when using WITH SLOTS.
> They wrote the (vitual) slot names they needed, and that got
> transformed (via the DSL) into something like
> (parse-integer huge-array :start start-of-that-column :end end-of-that-column)
> or even
> (let (slotx (parse-integer ...))
>   &body)
> 
> All the users need to know is the name SLOTX, which they declared
> themselves via the DSL that describes each line. The rest was MACRO
> and LAMBDA.
> 
> In the most recent such application, I made use of CLOS because it has
> a nice declarative touch) for configuration only. At the time each
> line is processed, nothing was using CLOS anymore. FUNCALL was it.
> 
> Regards,
> 	Jorg Hohle
> Telekom/T-Systems Technology Center