From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,fcc2d88d867060e8 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-12-27 14:51:50 PST Path: archiver1.google.com!news2.google.com!newsfeed2.dallas1.level3.net!news.level3.com!news-out.visi.com!hermes.visi.com!199.184.165.244.MISMATCH!rcn!feed3.news.rcn.net!not-for-mail Sender: jsa@rigel.goldenthreadtech.com Newsgroups: comp.lang.ada Subject: Re: load and use a ".o" file? References: <132Fb.3462$I02.2996@newssvr23.news.prodigy.com> From: j-anthony@rcn.com (Jon S. Anthony) Date: 27 Dec 2003 17:55:40 -0500 Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii NNTP-Posting-Host: 207.172.132.176 X-Trace: 1072565509 reader3.news.rcn.net 4739 207.172.132.176:42656 X-Complaints-To: abuse@rcn.com Xref: archiver1.google.com comp.lang.ada:3863 Date: 2003-12-27T17:55:40-05:00 List-Id: Stephen Leake writes: > j-anthony@rcn.com (Jon S. Anthony) writes: > > > This sort of thing is perfectly reasonable and something that is > > extremely useful in a wide range of applications. > > > > What I don't understand is why people don't just use technology that > > has solved this problem since "for ever". No, dll's and so's are not > > the answer - they are intended to solve a different (related) problem > > and are at best a poor mans hack for what you are talking about. > > > > What you really "need"[1] here is a true dynamic language. > > Ok, I'll bite. What's a "true dynamic language"? It is true that many folks will/do have different ideas about what "true dynamic language" means. In this respect I fear it is a bit like "true object oriented language". One characteristic that is neither necessary nor sufficient for any notion of this is that it be an "interpreted language". While some languages (for example, most scripting languages) do imply (mostly because the language specification _is_ the implementation) interpretation as part of their definition, "interpreted" interpreted properly is really an _implementation_ issue, _not_ a language issue. I think most people in the "dynamic community" would say you need at least the following characteristics to be "truly dynamic": 1. Dynamic typing. This is, strong typing on _objects_ as differentiated from "variables/locations". 2. Complete introspection of the language's computation and type model. This is directly and explicitly available at the level of the programmer (not just the implementer). NOTE: This does _not_ mean or imply access to the underlying _implementation_. Some things this _does_ imply: * New function objects may be added to a running system at any time and existing functions may be so modified at any time. * The ability to create new types and/or classes at runtime; modify existing classes (with complete instance migration). A couple examples which fully have this would be Common Lisp and Smalltalk. Neither are "interpreter" based[1]. Most Common Lisp implementations have optimizing native compilers that typically produce code within about 1.5-2.5 of well crafted C code[2]. So, "interpretation" of either source or byte code is not a relevant factor/issue. For more information, here are a couple of links: "Open Source/Free Software" Implementations: http://www.cliki.net/Common%20Lisp%20implementation Commercial Implementations: http://alu.cliki.net/Implementation General community information: http://www.cliki.net/index and, of course, c.l.l Here are a couple very simple examples concerning the issue at hand of the OP. These are done in Allegro Common Lisp at the REPL (read eval print loop), typically this sort of interaction would be through the IDE. CL-USER(1): (defun foo (l r) (declare (fixnum l r) (optimize (speed 3 safety 1 debug 1))) (+ l r)) => FOO CL-USER(2): (compile 'foo) => FOO CL-USER(3): (disassemble 'foo) ; Just to show we are native (on Intel...) ;; disassembly of # ;; formals: L R ;; code start: #x7140a65c: 0: 83 f9 02 cmpl ecx,$2 3: 74 02 jz 7 5: cd 61 int $97 ; EXCL::TRAP-ARGERR 7: 80 7f 97 00 cmpb [edi-105],$0 ; SYS::C_INTERRUPT 11: 74 02 jz 15 13: cd 64 int $100 ; EXCL::TRAP-SIGNAL-HIT 15: 03 c2 addl eax,edx 17: f8 clc 18: 8b 75 fc movl esi,[ebp-4] 21: c3 ret This example shows compiling and loading a set of resources from a file under program control. ;;;--------------------junk.cl------------ (in-package :cl-user) (defun foo (l r) (declare (fixnum l r) (optimize (speed 3 safety 1 debug 1))) (+ l r)) (defun bar (msg) (format nil "Here's a message: ~A" msg)) ;;;-----------------end junk.cl------------ ;;;---------------------load-from.cl----------- (in-package :cl-user) ;;; Load the function definitions (and other forms) in the file ;;; identified by FILESPEC (a pathname or a string which is a legal ;;; filespec for the underlying OS filesystem). Compile the file ;;; before loading it. ;;; ;;; WHEN-UNDEFINED indicates a level of conditionality for compiling ;;; and loading the file. If not given, or explicitly set to NIL, ;;; unconditionally compile and load the file. ;;; ;;; If given, it must be a list of function names, which are tested to ;;; see if they are currently defined. If _none_ of them are, then ;;; compile and load the file. ;;; ;;; NOTE: no current provision for checking to see if the definitions ;;; in the file are of a later time stamp than the current existing ;;; function definitions (which could be used to conditionally compile ;;; and load when definitions are superceded). ;;; ;;; Errors and serious conditions are handled by sending a message on ;;; the condition to the standard error stream. ;;; ;;; Returns t if file is successfully compiled and loaded, :noaction ;;; if no action is taken (see above), :error if an error is signaled ;;; or :serious if a serious condition is signaled. ;;; (defun load-from (filespec &key (when-undefined nil)) (assert (listp when-undefined)) (handler-case (if (or (eql when-undefined nil) (reduce #'(lambda (x y) (and x (not (fboundp y)))) when-undefined :initial-value t)) (load (compile-file filespec)) :noaction) ;; Exceptions ;; (error (condition) (format *error-output* "LOAD-FROM crashed with ~S" condition) :error) (serious-condition (condition) (format *error-output* "LOAD-FROM questionable: ~S" condition) :serious))) ;;;-----------------end load-from.cl----------- ;;; Load the previously compiled load-from object CL-USER(1): (load "load-from") ; Fast loading load-from.fasl T CL-USER(2): (foo 1 2) Error: attempt to call `FOO' which is an undefined function. [condition type: UNDEFINED-FUNCTION] CL-USER(4): (fboundp 'foo) NIL foo is undefined... CL-USER(5): (load-from "./junk.cl" :when-undefined '(load-from)) :NOACTION Since load-from is already defined, this does nothing per the spec. CL-USER(6): (load-from "./junk.cl" :when-undefined '(foo bar)) ;;; Compiling file ./junk.cl ;;; Writing fasl file ./junk.fasl ;;; Fasl write complete ; Fast loading /opt/GoldenThread/ExampleApps/ECDemo/junk.fasl T CL-USER(7): (foo 1 2) 3 CL-USER(8): (bar "Hello world!") "Here's a message: Hello world!" > Do you mean "interpreted from source" No, as this is an implementation issue. > Or "interpreted from some intermediate byte code", like most Visual > Basic, Lisp implementations, Java, C#, etc? No, as this is an implementation issue. BTW, _most_ Lisp implementations have _native compilers_. Some (e.g., CMUCL) _only_ have native compilers - no interpreter at all. > Or something else? Yes, as described above. > All interpreters make the job of adding random code at run-time much > easier. Actually, this only seems to be true; with fully compiled versions _this aspect_ is just as easy. The hard part, of course, is still the bits that make up the difference between a compiler and interpreter. /Jon [1] The ANSI Common Lisp specification http://www.lispworks.com/reference/HyperSpec/Front/index.htm requires a compiler, though not necessarily a native code generator. I'm much more familiar with Common Lisp than Smalltalk, but VisualWorks, Squeak, and VisualAge all have JIT compilers. Python offers some of this as well, but the "definition/reference implementations" are interpreted. [2] There are several types of basic block structures where CL can perform better than such C code.