From: Pascal J. Bourguignon on
"bartc" <bartc(a)freeuk.com> writes:

> "Pascal J. Bourguignon" <pjb(a)informatimago.com> wrote in message
> news:87ocm59gf8.fsf(a)galatea.local...
>> Walter Banks <walter(a)bytecraft.com> writes:
>>
>>> Once low level access was available we found that DSP programs
>>> could be written in C and take advantage of the compiler optimization
>>> and data management.
>>
>> This is good.
>>
>> The same of course can be and has been done for compilers of other
>> programming languages.
>>
>>
>> This kind of modification of the language is something that is useful
>> for all applications, not only for low level processor access. In any
>> application domain, you may need to have some domain specific language
>> extensions in the compiler. That's where Lisp shines: you can easily
>> modify or extend the lisp language, from user code, without a need to
>> modify and recompile the compiler itself, thanks to the metalinguistic
>> features and homoiconicy of lisp.
>
> But there's a steep learning curve for Lisp. Before you can do much with it,
> you have to confront difficult ideas that in other languages you may not
> have to bother with for years, if ever.
>
> (For example, what on earth do metalinguistic and homoiconicy mean;
> I'm sure these never came up in K&R2)

(metalinguistic is a kind of metaprogramming involving the creation of
another language above the current language. Writing a compiler is
metalinguistic. But in lisp, this can be done piecemeal: you can
easily reuse parts of lisp to implement your own domain specific
language (DSL). Homoiconicity is when the syntax to write data is
the same as the syntax to write code (if there is a syntax to write
data!). For example, in C, the syntax to write data is that of
literal numbers, literal strings, and structure and vector
initializations:

/* code: */
struct { int x; char* c; struct { int x,y; }} s[2] =
/* data: */
{{1,"Hello",{10,20}},
{2,"Bye",{20,30}}}
/* code: */
;
if(s[0].x==1){
{ int y=2; dosomething(s[0],y); }
{ int z=3; dosomethingElse(s[1],z); }
}

There you can see that the syntax to write data is more limited than
that to write code, and it is different (you use comma instead of
semicolon, you must add a comma between sublists of data, not so
between blocks of code).

In lisp, we use the same syntax for code and data:

(let ((s ' ; code
((1 "Hello" (10 20) symbols and forms are also data) ; data
(2 "Bye" (20 30) (if (= a 1) (print 'hi)) )) ; data
)) ; code
(if (= (first (elt s 0)) 1)
(progn
(let ((y 2)) (do-something (elt s 0) y))
(let ((z 3)) (do-something-else (elt s 0) z)))))

Actually, we can transform this whole block of code into data:

'(let ((s ' ; code
((1 "Hello" (10 20) symbols and forms are also data) ; data
(2 "Bye" (20 30) (if (= a 1) (print 'hi)) )) ; data
)) ; code
(if (= (first (elt s 0)) 1)
(progn
(let ((y 2)) (do-something (elt s 0) y))
(let ((z 3)) (do-something-else (elt s 0) z)))))

just prefixing it with this quote. With this homoiconicity property,
it becomes very easy to process code as data and also to extend the
language, processing data as integrated code (with macros, which are
not c pre-processor textual macros).
)


>> But I guess we're moving away from the subject.
>
> I guess so.

--
__Pascal Bourguignon__
From: BGB / cr88192 on

"Pascal J. Bourguignon" <pjb(a)informatimago.com> wrote in message
news:87ws0s8qy4.fsf(a)galatea.local...
> "bartc" <bartc(a)freeuk.com> writes:
>
>> "Pascal J. Bourguignon" <pjb(a)informatimago.com> wrote in message
>> news:87ocm59gf8.fsf(a)galatea.local...
>>> Walter Banks <walter(a)bytecraft.com> writes:
>>>
>>>> Once low level access was available we found that DSP programs
>>>> could be written in C and take advantage of the compiler
>>>> optimization
>>>> and data management.
>>>
>>> This is good.
>>>
>>> The same of course can be and has been done for compilers of other
>>> programming languages.
>>>
>>>
>>> This kind of modification of the language is something that is useful
>>> for all applications, not only for low level processor access. In any
>>> application domain, you may need to have some domain specific language
>>> extensions in the compiler. That's where Lisp shines: you can easily
>>> modify or extend the lisp language, from user code, without a need to
>>> modify and recompile the compiler itself, thanks to the metalinguistic
>>> features and homoiconicy of lisp.
>>
>> But there's a steep learning curve for Lisp. Before you can do much with
>> it,
>> you have to confront difficult ideas that in other languages you may not
>> have to bother with for years, if ever.
>>
>> (For example, what on earth do metalinguistic and homoiconicy mean;
>> I'm sure these never came up in K&R2)
>
> (metalinguistic is a kind of metaprogramming involving the creation of
> another language above the current language. Writing a compiler is
> metalinguistic. But in lisp, this can be done piecemeal: you can
> easily reuse parts of lisp to implement your own domain specific
> language (DSL). Homoiconicity is when the syntax to write data is
> the same as the syntax to write code (if there is a syntax to write
> data!). For example, in C, the syntax to write data is that of
> literal numbers, literal strings, and structure and vector
> initializations:
>
> /* code: */
> struct { int x; char* c; struct { int x,y; }} s[2] =
> /* data: */
> {{1,"Hello",{10,20}},
> {2,"Bye",{20,30}}}
> /* code: */
> ;
> if(s[0].x==1){
> { int y=2; dosomething(s[0],y); }
> { int z=3; dosomethingElse(s[1],z); }
> }
>
> There you can see that the syntax to write data is more limited than
> that to write code, and it is different (you use comma instead of
> semicolon, you must add a comma between sublists of data, not so
> between blocks of code).
>
> In lisp, we use the same syntax for code and data:
>
> (let ((s ' ; code
> ((1 "Hello" (10 20) symbols and forms are also data) ; data
> (2 "Bye" (20 30) (if (= a 1) (print 'hi)) )) ; data
> )) ; code
> (if (= (first (elt s 0)) 1)
> (progn
> (let ((y 2)) (do-something (elt s 0) y))
> (let ((z 3)) (do-something-else (elt s 0) z)))))
>
> Actually, we can transform this whole block of code into data:
>
> '(let ((s ' ; code
> ((1 "Hello" (10 20) symbols and forms are also data) ; data
> (2 "Bye" (20 30) (if (= a 1) (print 'hi)) )) ; data
> )) ; code
> (if (= (first (elt s 0)) 1)
> (progn
> (let ((y 2)) (do-something (elt s 0) y))
> (let ((z 3)) (do-something-else (elt s 0) z)))))
>
> just prefixing it with this quote. With this homoiconicity property,
> it becomes very easy to process code as data and also to extend the
> language, processing data as integrated code (with macros, which are
> not c pre-processor textual macros).
> )
>

it is a tradeoff...

lack of these sorts of macro facilities for sake of gaining a more
conventional syntax.
in the minds of probably many/most programmers, this is likely a worthwhile
tradeoff.

granted, a more limited macro facility can be added to a C-style syntax (I
have done so before), but in practice I didn't find it added a whole lot of
value (and so was not generally retained in subsequent languages).

in general, it is because most languages tend to be extended in terms of
functions/types/classes/... rather than by tweaking out the syntax. it may
be actually the case that it helps with conceptual regularity.

A is a class, B is a class, they have different contents but the same "look
and feel"...
for the hard-core, there are templates / generics...

granted, neither of these is really all that generic, and neither allows
arbitrary code building, but in practice this does not matter so much...
(and could be added anyways in a tweaked form, such as generics with
compile-time condionals and first-class symbols, ...).


>
>>> But I guess we're moving away from the subject.
>>
>> I guess so.
>
> --
> __Pascal Bourguignon__


From: BGB / cr88192 on

"Pascal J. Bourguignon" <pjb(a)informatimago.com> wrote in message
news:87k4wt9g3n.fsf(a)galatea.local...
> "Charles E. Bortle, Jr." <charlesb.cca(a)mpowercom.net> writes:
>
>> But I would add two wrinkle to your statment.
>> You could write an OS in, say, Pascal, but the
>> general implementation of the Pascal language,
>> at least the implementations I have used, do not
>> produce stand-alone code for a bare CPU, which
>> is often the platform in view when "OS" is mentioned.
>> I would qualify Any Programming Language and
>> say any General Purpose Programming Language
>> (Of course, that is really the Turing definition)
>
>
> The important point here is that it is not a question of language, but
> a question of implementation.
>
> Apple had no difficulty to write their system in Pascal. (Ok, the
> MacOS "kernel" was written in 68000 assembler, only the "Toolbox" was
> written in Pascal).
>

granted.
actually, FWIW, a kernel could probably be written in Pascal, although doing
so would be "unorthodox" (since it is generally known that C is the accepted
language of kernel writing), and as I see it, would not offer much real
benefit in these regards.


>
> There's also the question of "standard library", which may be thought
> of as non optional and pose problems in a barebone implementation,
> but it should not, really. Even the current C standard specifies a
> "standard library", which you have to ignore when writing a unix
> kernel. Modula-2 would be the most barebone language I know (and I
> guess Oberon is similar).
>

yes, but it is notable that C is very capable even without this library, and
in fact, a large amount of core algorithmic code will tend not to use it
much anyways.

some other languages (such as Java), would be almost unusably "gimped" if
their runtime libraries are taken away.

granted, as a gain, JBC is fairly simple, but as a cost, it is only really
useful for languages operating in a similar "window".

MSIL offers a wider window, but is somewhat more complex, and requires much
more of the VM, and x86 offers a fairly wide window, and does not make overt
demands, but does impose some on the "architecture" (one has to fake a lot
of esoteric bit-twiddly, and essentially run the code in a different address
space).

I had considered the possibility of an x86 subset/variant which could be
verifiable and word-size independent (allowing it to be JIT'ed into a host
address space), and had partly designed this, but this has not gone that
far... (it would be sort of like EBC, but more general purpose, and with
more traditional registers and semantics...). as a possible downside, it
would likely still be needed to thunk function calls (probably
automatically...).


anyways, not all traditional kernels are "unix" kernels, for example, there
is the Windows kernel, Mac OSX kernel, ... which operate in many of the same
ways.

I even have an interpreter which follows a similar architecture, ...


> --
> __Pascal Bourguignon__


From: jebblue on
On Sat, 05 Dec 2009 18:59:54 -0500, Bill Cunningham wrote:

> One reason why I am so attracted to C and not just markup languages
> scripts and java is that C is for designing OS's. What exactley is it
> about C that makes it good to right operating systems?
>
> Bill

I don't contribute many articles to USENET and most are usually
brief but ... C sux.

--
// This is my opinion.
From: [Jongware] on
Pascal J. Bourguignon wrote:
> "Charles E. Bortle, Jr." <charlesb.cca(a)mpowercom.net> writes:
>
>> But I would add two wrinkle to your statment.
>> You could write an OS in, say, Pascal, but the
>> general implementation of the Pascal language,
>> at least the implementations I have used, do not
>> produce stand-alone code for a bare CPU, which
>> is often the platform in view when "OS" is mentioned.
>> I would qualify Any Programming Language and
>> say any General Purpose Programming Language
>> (Of course, that is really the Turing definition)
>
> The important point here is that it is not a question of language, but
> a question of implementation.
>
> Apple had no difficulty to write their system in Pascal. (Ok, the
> MacOS "kernel" was written in 68000 assembler, only the "Toolbox" was
> written in Pascal).

An interesting tidbit: current Macs boot up using Forth bytecode.
http://osxbook.com/book/bonus/ancient/whatismacosx/arch_boot.html

"You can enter Open Firmware by pressing the key combination cmd-opt-O-F
just as you power on a Macintosh."

(where, presumably, "O-F" stands for "Open Firmware".)
As I know this much -> . about Forth, I didn't actually have the guts to
try this out :-)

[Jw]