Re: Why C for operating systems
- From: "BGB / cr88192" <cr88192@xxxxxxxxxxx>
- Date: Sat, 12 Dec 2009 10:09:36 -0700
"Pascal J. Bourguignon" <pjb@xxxxxxxxxxxxxxxxx> wrote in message
news:87ws0s8qy4.fsf@xxxxxxxxxxxxxxxx
"bartc" <bartc@xxxxxxxxxx> writes:
"Pascal J. Bourguignon" <pjb@xxxxxxxxxxxxxxxxx> wrote in message
news:87ocm59gf8.fsf@xxxxxxxxxxxxxxxx
Walter Banks <walter@xxxxxxxxxxxxx> 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__
.
- References:
- Why C for operating systems
- From: Bill Cunningham
- Re: Why C for operating systems
- From: Walter Banks
- Re: Why C for operating systems
- From: bartc
- Why C for operating systems
- Prev by Date: ~~~~~~~~~~~~~~ MOVIE WAV ~~~~~~~~~~~~~~
- Next by Date: Re: Different datastructures for different situations
- Previous by thread: Re: Why C for operating systems
- Next by thread: Re: Why C for operating systems
- Index(es):
Relevant Pages
|