"Paul Chapman" <[hidden email]> wrote in message
news:9foj3m$3bg$[hidden email]... > Eliot, > > [I find I'm not comfortable with the nested >s approach to quoting, so I'm > going to revert to the CompuServe convention which was the first I was > exposed to. If anyone feels this is a breach of Usenetiquette, please let > me know.] > > >>ANSI defines that blocks are recursive and have local temporaries<< > > Does that mean that block parameters are also local? Wouldn't this break > code which uses the (eg, final) value of a parameter outside the block? > > >>During this walk one will naturally detect if the return point is on the > same stack<< > > I get it. > > >>redesign the instruction set to support the ANSI standard definition of > blocks<< > > A good idea. > > I went looking for a copy of the standard on the web, but the links I > were broken. Having served many years ago on the APL standards committee, I > remember that draft standards are freely available, but that ISO/ANSI like > to get their money for the real thing. I guess I might have to shell out. > > Of course, this is not a hint to anyone here that they email me any copy of > the final draft they might have lying around on their hard drives: that > would be a breach of copyright. > > >>You want to read Dave Simmons' posts on selector namespaces in the AOS and > SmallScript engines then. Dave has taken this farther than any other > Smalltalk implementor I know of. He has done selector namespaces and > multi-methods<< > > I have already observed that many of Dave's ideas coincide with mine, even > though mine were developed independently (honest!). It happens to me all the time <g>. I have built things and then some time later find out that someone else has independently designed the same or similar thing. That just says to me that these are fundamental ideas in CS. > My ideas for language > extensions to make Smalltalk "seem like" a functional/procedural language > are also very similar to his, although my approach will be to supply > multiple, open-source compilers for different "views" of the underlying OO > mechanism (all compiling code for the same VM, of course). The AOS Platform (upon which SmallScript is built) provides that same facility. So too, does the Microsoft.NET Platform. I.e., a universal virtual machine (object model, execution engine, etc). > > In my scheme, for example, the expression "Sin (x)" is a message send with > receiver "Sin" (a poolDictionary entry of class Function), argument "x", and > a new kind of selector (a "call selector"?) which is nevertheless treated > the same way as Smalltalk selectors by the VM. I haven't yet looked deeply > enough into Dave's approach to find out if it's similar. In SmallScript, there are additional message forms: dot-msg, parenthetical, array-slice, property, etc. x.y; foo(...); [...][...]...; {...} Eval [ |s| := 'foobar' copy. s[1] := $F. |b| := s[4:7]. "" A regular expression used in a slice |t| := (b = s[`b.*']). "" <t> ==> <true> "" A regular expression replace assignment s[`b.*'] := 'Barsoom'. "" ==> 'FooBarsoom' ""Actually compiled as: s[`b.*']('Barsoom'). ]. Which would be declared as: Method behavior: String [ [<RegEx>rx](v) ... ]. ================= Here are some parenthetical-msg-forms. self foo(...) self.foo(...) foo(...) The compiler will attempt to resolve the "message" name for a parenthetical form, as a variable. If it cannot resolve it as a variable, then it will issue it as a message form. Thus given the expression: foo(...) a) Attempt to resolve <foo>. If resolved, then the message is #(...) and will be sent to <foo>. Noting that, by definition, #(...) messages are aliased to #value... messages. For example: Eval [ |foo| := [:a| a+a]. foo(1) "" ==> returns 2 ]. b) If the resolution fails, then treat it as a message of the form #foo(...) and send that message to <self> as a function send. The function send will try to resolve it as an instance method, but if that fails it will look for methods in the visible namespaces (which includes functions in DLL's). Noting that the class and superclasses are part of the visible namespaces, and so there methods will be resolved. Therefore we can write: |s| := String(10). Which is the same as: |s| := String new: 10. Because: <Constructor> defines #value to invoke #new. <Constructor> defines #value: to invoke #new:. Object Behavior Constructor Class Metaclass As in: ----- Method behavior: Constructor [ value: arg ^self new: arg ]. OR: (as it is actually declared) ----- Method behavior: Constructor [ (arg) tail:return(self new) ]. We can declare parenthetical messages as in: Method behavior: Bar [ foo(arg) ... ]. By default, the symbol manager will automatically alias single argument parenthetical messages to their #name: equivalent. It will similarly alias objective-c style message forms to their parentical representation. So the above declaration is identical to declaring: Method behavior: Bar [ foo: arg ... ]. Similarly, to see this form, mapped to Objective-C: --- Method behavior: Bar [ foo(arg1, arg2) ... ]. Is identical to declaring (objective-c style): Method behavior: Bar [ foo: arg1 : arg2 ... ]. Which can be evaluated equivalent as in: eval [ "" The following expressions will result in the "" same code sequence and resulting method invocation. "" One variant style Bar().foo(1,2). "" Another variant style Bar() foo(1,2). "" Classic Smalltalk with an Obj-C style message Bar new foo: 1 : 2. "" Which is exactly the same as (Bar new) foo: 1 : 2. "" Which theoretically could be treated by the AOS "" platform symbol machinery as: (but isn't) (Bar new) foo: 1 with: 2. ]. NOTE: The "." message form has a different precedence, and it will attempt to statically resolve references at compile time. Methods can also have two different names to enable unification of parenthetical forms with keyword message forms. This is a key feature for dealing with external languages. Method behavior: Blah [::altName(<>,<>) a: arg1 b: arg2 ... ]. Where we can invoke it identically as: eval [ |v| := Blah(). "" same as "Blah new" "" Classic st-style v a: 1 b: 2. "" Or obj-c style v altName: 1 : 2. "" OR v altName(1,2). "" Or v.altName(1,2). ]. "" Or looking at an instance method form Method behavior: Blah [ msg "" Classic st-style self a: 1 b: 2. "" Or obj-c style self altName: 1 : 2. "" OR self altName(1,2). "" Or self.altName(1,2). "" Or altName(1,2). ]. > > >> > > Ask me later whether interfaces are first-class objects -- ie when I > figure > > out what they are. > > It wouldn't be Smalltalk if they *weren't* first-class :) > << Interfaces are first class objects in SmallScript <g>. They can also provide concrete mixin behavior and are part of the type system. Interface name: Y inst-vars: a,b class-vars: c,d shared-vars: e,f ... [ Method [ someMsg ... ]. ]. "" End Interface Y "" OR Interface name: Y { Method [ someMsg ... ] } "" End Interface Y === Other Examples === Interface name: X. Class name: Blah implements: X. Class name: Bleck implements: X. --- Eval [ Blah() isKindOf: X) "" ==> returns <true> Bleck() isKindOf: X) "" ==> returns <true> ]. "" Or using multi-method declarations we can write "" a method which will only bind for <Blah | Bleck> Function [ abc(<Blah|Bleck> anX) ... ]. "" or we can generalize it to bind on <X>'s. Function [ abc(<X> anX) ... ]. "" or parameterized types. Method behavior: SomeClass [ abc(<X|self> anXOrSelf) ... ]. "" or parameterized types where arg2 "" must be a kind-of anX.behavior "" (there are many more variations on this theme "" for in/out args, array specifications, etc) Method behavior: SomeClass [ abc(<X> anX, <anX> arg2) ... ]. "" Or using multi-method declarations Method behavior: SomeClass ["" Same as ::abc(<>) abc: <X> anX ... ]. "" Or using multi-method declarations for a class-method Method behavior: SomeClass.class [ abc: <X> anX ... ]. "" Or going further and scoping it Method behavior: SomeClass.class scope: SomeLexicalScope [ abc(<X> anX) ... ]. "" Or Method behavior: SomeClass.class scope: private [ abc: <X> anX ... ]. "" Or Method behavior: SomeClass.class scope: A.B.C [ abc: <X> anX ... ]. "" Or Method behavior: SomeClass.class scope: A.B.C before [ abc: <X> anX ... ]. "" Or Method behavior: SomeClass.class scope: A.B.C [<$before> abc: <X> anX ... ]. "" Or Method behavior: SomeClass.class scope: A.B.C after [ abc: <X> anX ... ]. "" Or Method behavior: SomeClass.class scope: A.B.C [<$after> abc: <X> anX ... ]. "" Or Method behavior: SomeClass.class scope: A.B.C around [ abc: <X> anX ... ]. "" Or Method behavior: SomeClass.class scope: A.B.C [<$around> abc: <X> anX ... ]. etc. > > :-) > > >>My person-year estimate is based on a C implementation<< That's a minimum for an experienced VM designer to build a reasonable base implementation. > > It'll be C in the end, naturally. Why not Eiffel, or ML? Or, if you're really looking to experiment quickly, why not build on an existing open-source Lisp/scheme implementation? > > Cheers, Paul > > |
Dave,
Thank you for your long and detailed reply, which has presented me with many interesting ideas. >> > I have already observed that many of Dave's ideas coincide with mine, even > though mine were developed independently (honest!). It happens to me all the time <g>. I have built things and then some time later find out that someone else has independently designed the same or similar thing. That just says to me that these are fundamental ideas in CS. << This explains why there's nothing on earth quite like VB. :-) >> dot-msg, parenthetical, array-slice, property, etc. x.y; foo(...); [...][...]...; {...} << I couldn't find any examples of {} in the rest of your message. I also intend to put a "." syntax in. I'm not sure I like the implications for lexical analysis, though -- and therefore the implications for very close attention by the programmer. But then again "." is also used for the decimal point, so I suppose the damage is already done. In my design (which remember is not a superset of Smalltalk, but another available source language) I shall probably use "," as a statement separator (actually an expression separator -- I have never liked the presence of "statements" in non-procedural languages). Also, in my design, "a.b" will usually carry the same kind of meaning as "a at: #b" or "a[#b]": ie, the argument passed to the "." method would be "#b". Is that the case in your approach? >> s[1] := $F. << I also envision this syntax, with similar semantics to yours. In my mind, "[]:=" is a message selector of some kind. The programmer has control over the semantics since he/she can rewite the "[]:=" method. I'm also toying with trying to make "a := 3" a message send. Of course, ":=" changes the value of the reference of the name "a" rather than the current referent of "a". Some object has to be interposed between "a" and its referent to receive the ":=" message; this object is probably best called a "slot". (I've only recently found out about "slots", so my nomenclature may be inappropriate and/or my semantics inaccurate). The "default" slot would delegate every message to its contents (formally using #doesNotUnderstand:, in practice by some cleverness in the VM for performance) apart from ":=". Formally, a slot would usually be an indexed pointer object of size 1; this avoids the infinite regression since #at:put: is not an assignment. There is a problem, though: when does a "variable" refer to its slot, and when to the contents of its slot (the "real" object)? The resolution seems to be to use the slot when the variable is used as a receiver, but the object (possibly via an implicit send of #slotContents) elsewhere. I may not pursue this. The semantics end up more convoluted than allowing the OO oddity of assignment (although they would be invisible to Smalltalk programmers who don't know about them). OTOH, slots add daemons (which I have also recently learnt about) as fundamental. I'll get back to you on this. >> |b| := s[4:7]. << Can the programmer change the semantics of this syntax? I'm assuming that there's a selector here, something like "[:]", for which I can define my own method. Is that right? >> "" A regular expression used in a slice |t| := (b = s[`b.*']). "" <t> ==> <true> << Interesting that you've added regular expressions to the base image. I view (proper) programming languages as divided into four categories: procedural, functional, OO and logic/backtracking. The last category is the one I've had least experience of, although I did once implement a true LR(K) parser (in, guess what? APL). I do remember doing a short course in Snobol at college, but I've forgotten all of fit. And I've never had to learn Perl. :-) >> Method behavior: String [ [<RegEx>rx](v) ... ]. << I assume <RegEx> is a type. Is it compulsory or optional in this declaration? >>by definition, #(...) messages are aliased to #value... messages<< Hmm. I had not thought of this approach. The natural way that blocks become "functions" is nice (although of course the ZeroArgumentBlock method with selector "()" can be defined as "self value" for the same behaviour). >>If the resolution fails, then treat it as a message of the form #foo(...) and send that message to <self> as a function send<< I have to say I don't like this overloading of syntax. Admittedly there's nothing wrong with the bare name "foo" standing for a selector rather than an object -- we already have this with unary message syntax. But that's not perfect -- how many times a day do you debug '"self" not understood'? :-) I think I want to stick to the principal that the leftmost thing is always a receiver. >>Interfaces are first class objects in SmallScript <g><< Let me make things clear: they will of course be such in my system. :-) >>They can also provide concrete mixin behavior and are part of the type system<< I haven't yet given a great deal of though to types, although I strongly suspect they will be necessary for performance, even if not for expressivity or self-documentation, since the app in which my Smalltalk is to be embedded is real-time, and there are places where performance will be paramount. OTOH, maybe by the time it's finished, CPUs will be fast enough that I won't have to worry. :-) [I looked at the work the Self group did on runtime recompilation with both fascination and dismay. I can see they had a lot of fun, but the sad thing is that over the period of their study improvements in CPU speed achieved what they did and more. I have mixed feelings about the amount of effort put into optimization techniques. Then again, I have unmixed feelings about a world based on CISC architecture. Long live the ARM!] So I'll archive your type examples until I've had a change to think this through for myself. >> > > It'll be C in the end, naturally. Why not Eiffel, or ML? << Short answer: I have not used either language. Long answer: I'm trying both to understand the internals of the Smalltalk VM and design an OO language of my own. Just at the moment, I don't need a third new language in the mix. :-) [Aside: when I wrote I-APL I first designed and implemented a language in which to implement it. I-APL had to run on 64K machines because it was aimed at schools which in the mid-80s usually had access to little more than Z80- or 6502-based machines. It also had to be highly portable for the same reasons, and even be able to run from ROM. I therefore decided I needed a stack-based VM (this was before I ever encountered any VM-based language, or even knew the term). I looked at Forth, which was the natural existing choice, but compatibility of published implementations across different platforms would have been hell to resolve. In the end, my choice was right: I built an IDE (again, before I knew the term -- I called it "DE" and the language "DEL", which caused an unforseen problem in MSDOS the first time I tried to run the executable !:-) which provided a crash-proof emulation of the VM, breakpoints, watches, all of that. The source-code syntax was pretty, and added things that Forth didn't have. It took a month to write the IDE in C. Ah, those were the days when I could code FAST. Finally, the compiler was writen in STSC APL*PLUS/PC. It took 7 hours to run.] >> Or, if you're really looking to experiment quickly, why not build on an existing open-source Lisp/scheme implementation? << Same reason: don't know 'em. I learnt my skills on the practical side of the industry (APL: practical?), and so to my great shame have never used Lisp in anger, although I still have an archived paper design for a Z80 Lisp implementation -- in red ink, for some reason, I recall -- which never saw the light of day: I guess I must have been excited about it once. My college course did not cover Lisp, which annoys me still. I was introduced to Church's lambda notation, though, so I understand the functional principals. CLOS, OTOH, is nothing more than a name to me. :-( Cheers, Paul |
"Paul Chapman" <[hidden email]> wrote in message
news:9fp49b$v61$[hidden email]... > Dave, > > Thank you for your long and detailed reply, which has presented me with many > interesting ideas. > > >> > > I have already observed that many of Dave's ideas coincide with mine, even > > though mine were developed independently (honest!). > > It happens to me all the time <g>. I have built things and then some time > later find out that someone else has independently designed the same or > similar thing. That just says to me that these are fundamental ideas in CS. > << > > This explains why there's nothing on earth quite like VB. :-) > > >> > dot-msg, parenthetical, array-slice, property, etc. > x.y; > foo(...); > [...][...]...; > {...} > << > > I couldn't find any examples of {} in the rest of your message. > > I also intend to put a "." syntax in. I'm not sure I like the > for lexical analysis, though -- and therefore the implications for very > close attention by the programmer. But then again "." is also used for the > decimal point, so I suppose the damage is already done. Once it is in there for namespaces and other path forms, then to use your phrase, "damage is done". The important factor for me was providing similar functionality and appearance vis-a-vis other scripting/programming languages. > > In my design (which remember is not a superset of Smalltalk, but another > available source language) I shall probably use "," as a statement separator > (actually an expression separator -- I have never liked the presence of > "statements" in non-procedural languages). > > Also, in my design, "a.b" will usually carry the same kind of meaning as "a > at: #b" or "a[#b]": ie, the argument passed to the "." method would be "#b". > Is that the case in your approach? > > >> > s[1] := $F. []:= is mapped to the message: [...](rhsv) as in: [1]($F) Method behavior: sClass [ [indexA](value) ... ]. > << > > I also envision this syntax, with similar semantics to yours. In my mind, > "[]:=" is a message selector of some kind. The programmer has control over > the semantics since he/she can rewite the "[]:=" method. > > I'm also toying with trying to make "a := 3" a message send. Of course, > ":=" changes the value of the reference of the name "a" rather than the > current referent of "a". Some object has to be interposed between "a" and > its referent to receive the ":=" message; this object is probably best > called a "slot". (I've only recently found out about "slots", so my > nomenclature may be inappropriate and/or my semantics inaccurate). SmallScript supports automatic assignment coercion to messages for non-static expressions: a.b := 10. "becomes" a.b: 10. "which is effectively:" a b: 10. SmallScript also allows you to declare a method as a property, at which point you can use the message name as a variable. Property behavior: sClass [ x ^someExpression. ]. Property behavior: sClass [ x: value someExpression := value. ]. Method behavior: sClass [ someMsg ^x := x + 1. ]. The <x> here is not an inst-var, but actually a property method. The compiler will effectively generate the following code for the #someMsg method. Method behavior: sClass [ someMsg |t| self x: (t := self x + 1). ^t ]. ================= SmallScript also allows declaration of property-variables which are "lazily" allocated on a per-instance basis. I.e., you can declare 1000 property variables for a class. But, they will only be instantiated for a particular instance when they are assigned. Class name: X property-vars: a,b,c,d,e,f,g,h,i,j,... Method behavior: X [ someMsg a := 10. b := a. ^j ]. Unlike inst-vars, the property vars are maintained like python style variables, as a kind of hash-table entry within the object's properties. So, until the variables are assigned, they have no entry in the property system. When they are set back to their default (they may get their variable-slot removed from the property system). This technique allows one to add variables to individual instances of objects. Eval [ "" Asuming the previous X::someMsg method where <a> was assigned 10 | prev| := someX someMsg;{'a'}. "" See classic-st form next |r| := someX{'a'} :+= 1. "" uses mmdisp to discriminate "" Which is equivalent to: r := someX propertyVariableValueAt: 'a' put: (someX propertyVariableValueAt: 'a') + 1. "The value of <prev> is 10, and the value of <r> initially is 11" ]. > > The "default" slot would delegate every message to its contents (formally > using #doesNotUnderstand:, in practice by some cleverness in the VM for > performance) apart from ":=". Formally, a slot would usually be an indexed > pointer object of size 1; this avoids the infinite regression since #at:put: > is not an assignment. > > There is a problem, though: when does a "variable" refer to its slot, and > when to the contents of its slot (the "real" object)? The resolution seems > to be to use the slot when the variable is used as a receiver, but the > object (possibly via an implicit send of #slotContents) elsewhere. > > I may not pursue this. The semantics end up more convoluted than allowing > the OO oddity of assignment (although they would be invisible to Smalltalk > programmers who don't know about them). > > OTOH, slots add daemons (which I have also recently learnt about) as > fundamental. I'll get back to you on this. > > >> > |b| := s[4:7]. > << > > Can the programmer change the semantics of this syntax? I'm assuming that > there's a selector here, something like "[:]", for which I can define my > method. Is that right? Yes. The format is just a message. "" Getter Form Method behavior: SomeClass [ [arg1 : arg2]() ... ]. "" Setter (assignment) Form Method behavior: SomeClass [ [arg1 : arg2](value) ... ]. > > >> > > "" A regular expression used in a slice > |t| := (b = s[`b.*']). "" <t> ==> <true> > << > > Interesting that you've added regular expressions to the base image. I view > (proper) programming languages as divided into four categories: procedural, > functional, OO and logic/backtracking. The last category is the one I've > had least experience of, although I did once implement a true LR(K) parser > (in, guess what? APL). I do remember doing a short course in Snobol at > college, but I've forgotten all of fit. And I've never had to learn Perl. > :-) Ahh. Keeping in mind that one of my big focuses is "scripting" and that often relates to text processing, it was important to have basic text processing services. But the most important factor is that regular-expressions are actually implemented with full block closure semantics. So the RX expressions can contain/declare internal variables and filters/patterns written in SmallScript itself. To provide that functionality required making regular expressions a part of the language. > > >> > Method behavior: String [ > [<RegEx>rx](v) > ... > ]. > << > > I assume <RegEx> is a type. Is it compulsory or optional in this > declaration? <RegEx> is the base type for regular expression objects, as <Block> is the base type for block objects. All type declaration in SmallScript is optional. A type annotation can be treated as hint for marshalling or as a binding characteristic for multi-method dispatch. In this case, we have explicitly declared the (optional) type characteristic for multi-method binding of a given #[1](1) message. Thus we have said that the method should only "bind" when the <rx> argument is a "kind-of" <RegEx> object. Furthermore, the binder will also perform best-fit analysis if there are competing methods with the same selector but different type-signatures. I.e. "" The following is a generic form where <rx> can be of <any> type. Method behavior: String [ [rx](v) ]. Thus: Eval [ s[s] := ''. "" Would bind to the generic <any> signature version s[`.*'] := ''. "" Would bind to the <RegEx> signature version ]. > > >>by definition, #(...) messages are aliased to #value... messages<< > > Hmm. I had not thought of this approach. The natural way that blocks > become "functions" is nice (although of course the ZeroArgumentBlock method > with selector "()" can be defined as "self value" for the same behaviour). SmallScript doesn't have a ZeroArgumentBlock, etc. All blocks are uniform in the sense that there is one type for blocks independent of the number of arguments it takes (there is a subtype of block, called an UnloadedBlock, but it is not appropriate to explain that here). The "arity" of a block does not have to correspond to the "arity" of the valuation message. Example: Eval [ [10] value: 1 value: 2. "Perfectly ok" [:a| a] value. "Perfectly ok" ]. Here's the arity coercion rule: ------------------------------- Missing arguments are supplied as <nil>, and excess arguments are ignored. The same rules apply to various perform operations and valuation of method objects. Eval [ "" #foo someObject perform: #foo. someObject perform: #foo with: 10. "" #foo: someObject perform: #foo:. someObject perform: #foo: with: 10. ]. Eval [ |m| := someMethodInst. m value. "" m(). m value: 10. "" m(10). "" Or: m self: aReceiver. "" m self: aReceiver value: 10. ]. > > >>If the resolution fails, then treat it as a message of the form #foo(...) > and send that message to <self> as a function send<< > > I have to say I don't like this overloading of syntax. Admittedly there's > nothing wrong with the bare name "foo" standing for a selector rather than > an object -- we already have this with unary message syntax. But that's not > perfect -- how many times a day do you debug '"self" not understood'? :-) In practice, I've not seen this happen. Although I understand your concerns. Just keep in mind that my goals are for scripting language style application and practices. It is practically a cut & paste operation to move VB, JScript, Python, PHP, et cetera expressions into SmallScript and get them to run. > > I think I want to stick to the principal that the leftmost thing is always a > receiver. > > >>Interfaces are first class objects in SmallScript <g><< > > Let me make things clear: they will of course be such in my system. :-) > > >>They can also provide concrete mixin behavior and are part of the type > system<< > > I haven't yet given a great deal of though to types, although I strongly > suspect they will be necessary for performance, even if not for > or self-documentation, since the app in which my Smalltalk is to be embedded > is real-time, and there are places where performance will be paramount. > > OTOH, maybe by the time it's finished, CPUs will be fast enough that I won't > have to worry. :-) > > [I looked at the work the Self group did on runtime recompilation with both > fascination and dismay. I can see they had a lot of fun, but the sad thing > is that over the period of their study improvements in CPU speed achieved > what they did and more. I have mixed feelings about the amount of effort > put into optimization techniques. Then again, I have unmixed feelings about > a world based on CISC architecture. Long live the ARM!] The Self adaptive compilation technology is not based on using declarative type annotations. I chose to provide declarative type annotation facilities because they are fundamental for providing multi-methods and FFI interop. The performance optimization possibilities are also there as in any statically compiled language, but the optimization opportunities are *not* the reason for providing first-call types, type-signatures, and type-annotations. > > So I'll archive your type examples until I've had a change to think this > through for myself. > > >> > > > > It'll be C in the end, naturally. > > Why not Eiffel, or ML? > << > > Short answer: I have not used either language. > > Long answer: I'm trying both to understand the internals of the Smalltalk > and design an OO language of my own. Just at the moment, I don't need a > third new language in the mix. :-) > > [Aside: when I wrote I-APL I first designed and implemented a language in > which to implement it. I-APL had to run on 64K machines because it was > aimed at schools which in the mid-80s usually had access to little more than > Z80- or 6502-based machines. It also had to be highly portable for the same > reasons, and even be able to run from ROM. I therefore decided I needed a > stack-based VM (this was before I ever encountered any VM-based language, or > even knew the term). I looked at Forth, which was the natural existing > choice, but compatibility of published implementations across different > platforms would have been hell to resolve. I did a lot of work in Forth during the time period your talking about. It was pretty easy to build your own forth implementation in assembly language <g>. On the hobby (non-professional side) I was a big Atari 6502/6512 fan/devloper. I played a bit with the Z80 but never really got into it -- I didn't like the Timex Sinclair machines. Very early on in that period I happened to use APL quite a bit for about a year or so on HP machines at NIH (National Institutes of Health) through a "guest" account -- it was a fabulous language for doing Physics/Chemistry Labwork and building Dungeons & Dragons gaming tools ;-). Using thermal paper printouts on 110 then 300 and ultimately 1200 baud modems seemed great at that time, but I couldn't imagine doing it now. In that same period 1976-1984 I worked in the Scientific Computing Division at the National Bureau of Standards (NBS today known as NIST). I was working on unix with PDP's, HP machines, Univacs, (some more obscure systems), and Perkin-Elmer 16/32 bit machines and I also did a lot of work on CP/M. I designed and built a fair amount of from-scratch hardware systems using 6512's and 68K cpu's before I decided to be a full time software guy. Cheers, -- Dave S. [www.smallscript.net] > > In the end, my choice was right: I built an IDE (again, before I knew the > term -- I called it "DE" and the language "DEL", which caused an unforseen > problem in MSDOS the first time I tried to run the executable !:-) which > provided a crash-proof emulation of the VM, breakpoints, watches, all of > that. The source-code syntax was pretty, and added things that Forth didn't > have. It took a month to write the IDE in C. Ah, those were the days when > I could code FAST. > > Finally, the compiler was writen in STSC APL*PLUS/PC. It took 7 hours to > run.] > > >> > Or, if you're really looking to experiment quickly, why not build on an > existing open-source Lisp/scheme implementation? > << > > Same reason: don't know 'em. I learnt my skills on the practical side of > the industry (APL: practical?), and so to my great shame have never used > Lisp in anger, although I still have an archived paper design for a Z80 > implementation -- in red ink, for some reason, I recall -- which never saw > the light of day: I guess I must have been excited about it once. My > college course did not cover Lisp, which annoys me still. I was introduced > to Church's lambda notation, though, so I understand the functional > principals. CLOS, OTOH, is nothing more than a name to me. :-( > > Cheers, Paul > > |
David,
>> > Also, in my design, "a.b" will usually carry the same kind of meaning as "a > at: #b" or "a[#b]": ie, the argument passed to the "." method would be "#b". > Is that the case in your approach? << You skipped this question. I'm still interested in the answer. >> SmallScript also allows you to declare a method as a property, at which point you can use the message name as a variable. << Yup. Thinking about properties. They're the only things I ever liked about VB. >> SmallScript also allows declaration of property-variables which are "lazily" allocated on a per-instance basis << Easily simulated in Smalltalk, of course. For reasons which will become clearer later (both to the group and to me :-) I intend to introduce a class called something like FixedKeyDictionary, whose set of keys is fixed at object Construction. Use of this class in Smalltalk would more closely correlate to SmallScript's requirement that property variables be declared statically. OTOH, space is reserved in a FixedKeyDictionary for the values. >>Missing [value:...] arguments are supplied as <nil>, and excess arguments are ignored.<< Hmmm. This invites obscure bugs. It is a Bad Thing, IMHO. Many languages which allow for "optional arguments", for example, require that their respective parameters are declared as such. When I was young and naive, I did think a lot about how to design a low-level, APL-like language in which every "juxtaposition" (the syntax was "juxtopostition-based") of values, symbols, etc, meant something and therefore executed without error: if it compiles, it runs. I have since learned that run-time errors have a valuable role to play in speedy and reliable development. I've even found myself writing assertion code in languages which do not directly support the concept! (This provokes the question: can I at least find out how many parameters a SmallScript Block has at run-time? Can I rewrite the eg value: method to check for valence corrrespondence?) Smalltalk requires the programmer to declare temporary variables. This is purely a safety feature (and, thinking about it, just about the only one in the language). The fact that I have predominantly worked in APL and Smalltalk (and cast-happy C) should tell you I do not subscribe to the strict Ada/Eiffel approach when it comes to safety features. Is there an implementation reason for the relaxed-valence value:... rule in SmallScript? I hope so. :-) >>It is practically a cut & paste operation to move VB, JScript, Python, PHP, et cetera expressions into SmallScript and get them to run<< <shiver> <g> Aside: I think the clipboard is a great invention. And the nomenclature "Cut and Paste" is an inspired phrase. (Do we have Xerox PARC to thank for that? I guess so.) But when did "Copy" get added to the mix? It's more than fifty years since the closed subroutine was invented. (Its bastard son, the macro, has its uses, I suppose). Two years ago I was asked to review some VB code written by a "professional contractor". His design strategy was clearly something like this: "I need to do something like those 20 lines of code I wrote half-an-hour ago, so I'll just copy-and-paste them here, and change the variable that's different." He really *did* have "declarations like" (from Dave Harris, above): string addressLine1; string addressLine2; string addressLine3; string addressLine4; Ack! Anyway, all the code was thrown away and he was shown the door. (Six months later I heard he was earning pots of money sitting around in a bank reading the papers while the management tried to figure out what to do after a merger. I could do that job!) End of aside. >>The Self adaptive compilation technology is not based on using declarative type annotations<< Of course. I did not mean to imply anything to the contrary. >>On the hobby (non-professional side) I was a big Atari 6502/6512 fan/devloper. I played a bit with the Z80 but never really got into it -- I didn't like the Timex Sinclair machines<< I never used a Sinclair. My first micro was a SWTPC 6800. The first British micro was the Nascom-1, which was built around a Z80, and I had one of those (wrote a commercial symbolic assembler for it in 3K). I also did some real-time tape- and disk-controller firmware on the Z80 at that time. All in all, I ended up specializing in Z80 code, and wrote my first APL for the Z80. >>Using thermal paper printouts on 110 then 300 and ultimately 1200 baud modems seemed great at that time<< That was my first use of APL, too. Which is why I wanted an interpreter for micros. Of course, there was the IBM 5100, a bitslice microprocessor emulating a System/370 running IBM APL/SV! I even wrote a microcode cross-assembler for it in APL. (And, a propos another thread in this group, it was OS-less.) And my very first program ran in Fortran IV on an IBM 7094. It was supposed to print powers of 2 up to 50, but I immediately learnt a hard lesson about word-size. Cheers, Paul |
"Paul Chapman" <[hidden email]> wrote in message
news:9ftcn0$5bn$[hidden email]... > David, > > >> > > Also, in my design, "a.b" will usually carry the same kind of meaning as > "a > > at: #b" or "a[#b]": ie, the argument passed to the "." method would be > "#b". > > Is that the case in your approach? > << > > You skipped this question. I'm still interested in the answer. Sorry, I missed the question first time around. The "." is not a message, it is syntax to distinguish the message form/precedence. In the "a.b" expression, the message is #b. The a.b form, has the highest precedence. The compiler attempts to statically resolve each element in the form based on type information and inferencing. If it is unable to do so, it will convert any trailing (unresolved elements) into message sends. That said, "a at: #b" or "a[#b]" is just a message whose meaning is determined by the method hierarchy of "a behavior". As I think I mentioned before, #at: and #[1] are aliases, as is #at:put: and #[1](1). Reminder (in case I didn't make it clear), an alias is a distinct message selector, but will bind based on its primarySelector. Which allows the callee (if they care in say a DNR) to distinguish between an alias and its primary selector (or access the selector used by the caller via <thisSelector>). (DNR is the sequence: #forwardInvocation:withArguments, which typically falls through to #doesNotRespondTo:withArguments:). The use of <thisSelector> returns the original message selector used to invoke a particular method -- which enables obtaining the caller's message's scope and selector name. Note that with selector namespaces, one also has the ability to qualify a message with a particular namespace scope when invoking it. SmallScript allows one to write a message name as a full symbol or <MessageSignature> declaration. Where the "#" is the symbol (selector) declaration, and a "::" is a <MessageSignature> declaration. As part of SmallScript's consistency rules for declarations, one can write "a.b" as: a.#b a::b Or combine them: A.#::b In any of those forms, the compiler will provide the same precedence, but will limit its efforts to binding static elements. Note that those forms allow one to write code like: a << b.foo << b#foo:bar:(x,y). "" Which is the same as: a << (b foo) << (b foo: x bar: y). "" These forms can be used to ensure explicit "" message bindings or using additional annotations "" be used to force a static binding to a "" particular method implementation. Think, explicit "" annotation facilities similar to the <super> concept. A full message signature includes: <any custom annotations for the signature> <return-type-annotations> <scope><selector> <argument-type-annotations> One can use a signature to lookup a method in a dictionary: SomeClass[#::<returnType>scope.scope.selector(<type>,<type>)]. "or equivalently from QKS Smalltalk, pre-dating SmallScript" SomeClass<>#::<returnType>scope.scope.selector(<type>,<type>). "" Which I believe some Smalltalk's also define as #<< "" but which I do not because it is so commonly used for "" stream operations and bit-shifting that I preferred "" to avoid the confusion when I first developed QKS "" Smalltalk some ten years ago. It also allowed for "" variations like #<_>,#<&>, etc. Here are some examples of a scope qualified message send. a SomeNS.bar a #SomeNS.bar a ::SomeNS.bar a #::SomeNS.bar The "::" operator can also be applied to a parenthetical form to indicate that it "should" be treated as only a function binding and not a possible instance method. Method behavior: SomeClass [ someMsg foobar(). "" Will attempt to bind the instance "" "self foobar" then attempt to bind "" to a function in the method's visible "" scopes. "" vs. ::foobar(). "" Will go immediately to bind a foobar" "" function in the method's visible scopes. ]. The type annotation system also allows passing variables references (in/out) arguments which enables returning multiple values and plays a role in FFI marshalling. Eval [ |v| |b| := [:<out>a| a := 10. 11]. |r| := b value: <&>v. "" i.e., b(<&>v) ^v. "" r will be 10, and ^v will return 10 ]. The annotation system also allows declaring and passing &rest style position independent optional named arguments. But, I've said enough so I'm not going to explain that one now. > > >> > SmallScript also allows you to declare a method as a property, at which > point you can use the message name as a variable. > << > > Yup. Thinking about properties. They're the only things I ever liked about > VB. > > >> > SmallScript also allows declaration of property-variables which are "lazily" > allocated on a per-instance basis > << > > Easily simulated in Smalltalk, of course. > > For reasons which will become clearer later (both to the group and to me :-) > I intend to introduce a class called something like FixedKeyDictionary, > whose set of keys is fixed at object Construction. Use of this class in > Smalltalk would more closely correlate to SmallScript's requirement that > property variables be declared statically. OTOH, space is reserved in a > FixedKeyDictionary for the values. > > >>Missing [value:...] arguments are supplied as <nil>, and excess arguments > are ignored.<< > > Hmmm. This invites obscure bugs. It is a Bad Thing, IMHO. Many languages > which allow for "optional arguments", for example, require that their > respective parameters are declared as such. > > When I was young and naive, I did think a lot about how to design a > low-level, APL-like language in which every "juxtaposition" (the syntax was > "juxtopostition-based") of values, symbols, etc, meant something and > therefore executed without error: if it compiles, it runs. I have since > learned that run-time errors have a valuable role to play in speedy and > reliable development. I've even found myself writing assertion code in > languages which do not directly support the concept! > > (This provokes the question: can I at least find out how many parameters a > SmallScript Block has at run-time? Can I rewrite the eg value: method to > check for valence corrrespondence?) Smalltalk (SmallScript) provides full reflection services. So a block knows (and can be queried) for its "arity" (number of arguments as well as their type signatures, related annotations, etc). > > Smalltalk requires the programmer to declare temporary variables. This is > purely a safety feature (and, thinking about it, just about the only one in > the language). The fact that I have predominantly worked in APL and > Smalltalk (and cast-happy C) should tell you I do not subscribe to the > strict Ada/Eiffel approach when it comes to safety features. > > Is there an implementation reason for the relaxed-valence value:... rule in > SmallScript? I hope so. :-) It is crucially important that (efficient) flexible arity be allowed for perform and valuation. It enables substitutability for facilities like delegation and aspect-oriented/introspection-facilities. I learned this lesson early on in building QKS Smalltalk and designing the semantic message architecture for notification, delegation, transactions, etc. > > >>It is practically a cut & paste operation to move VB, JScript, Python, > PHP, et cetera expressions into SmallScript and get them to run<< > > <shiver> <g> <g> This is very important for easing through the adoption/learning/acceptance curve. OTOH, there is work underway on a number of compiler's for the AOS Platform. So many of these same languages will be directly available on the same execution architecture (whether it is the AOS Platform or the Microsoft.NET Platform). > > Aside: I think the clipboard is a great invention. And the nomenclature > "Cut and Paste" is an inspired phrase. (Do we have Xerox PARC to thank for > that? I guess so.) But when did "Copy" get added to the mix? > > It's more than fifty years since the closed subroutine was invented. (Its > bastard son, the macro, has its uses, I suppose). Two years ago I was asked > to review some VB code written by a "professional contractor". His design > strategy was clearly something like this: "I need to do something like those > 20 lines of code I wrote half-an-hour ago, so I'll just copy-and-paste them > here, and change the variable that's different." > > He really *did* have "declarations like" (from Dave Harris, above): > > string addressLine1; > string addressLine2; > string addressLine3; > string addressLine4; > > Ack! Anyway, all the code was thrown away and he was shown the door. > months later I heard he was earning pots of money sitting around in a bank > reading the papers while the management tried to figure out what to do after > a merger. I could do that job!) > > End of aside. > > >>The Self adaptive compilation technology is not based on using declarative > type annotations<< > > Of course. I did not mean to imply anything to the contrary. > > >>On the hobby (non-professional side) I was a big Atari 6502/6512 > fan/devloper. I played a bit with the Z80 but never really got into it -- I > didn't like the Timex Sinclair machines<< > > I never used a Sinclair. My first micro was a SWTPC 6800. The first > British micro was the Nascom-1, which was built around a Z80, and I had one > of those (wrote a commercial symbolic assembler for it in 3K). I also did > some real-time tape- and disk-controller firmware on the Z80 at that time. > All in all, I ended up specializing in Z80 code, and wrote my first APL for > the Z80. > > >>Using thermal paper printouts on 110 then 300 and ultimately 1200 baud > modems seemed great at that time<< > > That was my first use of APL, too. Which is why I wanted an interpreter for > micros. Of course, there was the IBM 5100, a bitslice microprocessor > emulating a System/370 running IBM APL/SV! I even wrote a microcode > cross-assembler for it in APL. (And, a propos another thread in this group, > it was OS-less.) > > And my very first program ran in Fortran IV on an IBM 7094. It was supposed > to print powers of 2 up to 50, but I immediately learnt a hard lesson about > word-size. > > Cheers, Paul > -- Dave S. [www.smallscript.net] |
David,
>>Reminder (in case I didn't make it clear), an alias is a distinct message selector, but will bind based on its primarySelector<< This is now clear. :-) More later. Cheers, Paul |
Free forum by Nabble | Edit this page |