From: Pascal J. Bourguignon on 12 Dec 2009 04:46 "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 12 Dec 2009 12:09 "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 12 Dec 2009 13:12 "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 13 Dec 2009 22:43 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 14 Dec 2009 06:21
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] |