Hi,
just before I go on holidays I decided to pack all the latest
improvements in the ECL source tree and make another 0.9 release. In
case you find bugs or problems building it, please report it using the
facilities in Source Forge (http://www.sourceforge.net/projects/ecls).
Otherwise, enjoy it!
Juanjo
Announcement of ECL v0.9f
=========================
ECL stands for Embeddable Common-Lisp. The ECL project aims to produce
an
implementation of the Common-Lisp language which complies to the ANSI
X3J13
definition of the language.
The term embeddable refers to the fact that ECL includes a lisp to C
compiler,
which allows to produce libraries (static or dynamic) that can be
called from C
programs. Furthermore, ECL can produce standalone executables from your
lisp
code.
ECL supports the operating systems Linux, FreeBSD, NetBSD, Solaris (at
least
v. 9), Microsoft Windows and OSX (including 10.4.2), running on top of
the
Intel, Sparc, Alpha and PowerPC processors. Porting to other
architectures
should be rather easy.
ECL is currently hosted at SourceForge. The home page of the project is
http://ecls.sourceforge.net, and in it you will find source code
releases, a
CVS tree and an up to date documentation.
Notes for this release
======================
This release includes many bug fixes, as well as performance
improvements. A
noticeable speed up happens at boot time, due to changes in the
implementation
of SUBTYPEP, which make type comparisons much faster, as well as some
fine
tuning of the garbage collector.
We have also introduced several bug fixes which seem to make ECL more
friendly
towards GCC 4.0 At least this means ECL now builds on my iBook without
additional configuration flags. Please report if you experience any
difficulties.
ECL 0.9g
========
* Platforms:
- Fixed the broken port for MacOSX. It should work with any release >=
10.2
- Based on version 6.5 of Boehm-Weiser garbage collector, which fixes
some
problems related to the OSX port.
- The latest version of Mingw32's GCC is broken. It silently ignores
pathnames
which end in '/'. The include options in ECL have been modified to
take
this into account but this intrinsic bug of Mingw might influence
ECL's
behavior in some other unexpected ways.
- The configuration in Solaris should now proceed with the flag
--enable-slow-conf.
* Foreign function interface (FFI):
- Added nickname UFFI for FFI package; functions
ALLOCATE-FOREIGN-STRING,
WITH-FOREIGN-STRING, WITH-FOREIGN-STRINGS, and FOREIGN-STRING-LENGTH
are now
exported. (M. Pasternacki)
- Ecl now accepts :CSTRING UFFI primitive type. (M. Pasternacki)
- DEF-FOREIGN-VAR rewritten to make variables visible from other files
and to
dereference also arrays and pointers. (M. Pasternacki)
- When creating a C-STRING, characters after the fill pointer are
discarded,
according to people's expectations.
* Compiler changes:
- Generated C functions now have readable names corresponding to
appropriate
Lisp function names (M. Pasternacki)
- ECL now compiles with the free Microsoft Visual C++ Toolkit
2003. Instructions are provided on how to do it.
- Unless SI:*KEEP-DOCUMENTATION* = NIL, the documentation of functions
is
stored in the compiled files.
- COMPILE-FILE now honors the value of :OUTPUT-FILE given by the user,
even if
they do no have the usual extension (.fas). Furthermore, LOAD will
now try
to load files with strange extensions (.fas, .fasl, etc) as binary
files and
only if this fails, use the source-file loader.
- .LSP/.LISP (notice uppercase!) are now recognized lisp source
extensions.
- We now provide inline expansions for all logical operators.
- We have changed the syntax both for function proclamantions and for
inline
expansions in sysfun.lsp Additionally, the checks for functions
having side
effects have been improved and inline expansions are now stored with
a
special-purpose structure INLINE-INFO.
* Errors fixed:
- Now .o files compiled with :SYSTEM-P T with dash in filename load
correctly. (M. Pasternacki)
- Incorrectly loaded files are now unloaded without falling into
infinite
loop. (M. Pasternacki)
- When ECASE or CTYPECASE signal a TYPE-EROR the TYPE-ERROR-DATUM is
the value
that originated the error.
- FDEFINITION did not signal a type error when passed things like
'(SETF A B).
- FUNCTION-LAMBDA-EXPRESSION does not fail, but does nothing useful,
when
passed a generic function.
- Trying to execute an instance object that is not a generic function
does no
longer crashes ECL.
- When signalling a READER-ERROR, the field reader-error-stream was
not bound.
- The random number generator assumed 32-bit integers.
- ext:run-program looks into *standard-input/output* and
*error-output* for handle
duplication also under Win32.
- FEtype_error_index() had format arguments in wrong order (M.
Goffioul).
- In the LOOP macro, variables are initialized with values of their
type, no
longer producing code like (LET ((C NIL)) (DECLARE (CHARACTER C))
...)
- The compiler now advertises itself with PROVIDE so that issuing
(REQUIRE
'CMP) twice does not cause the compiler to be loaded twice.
- Fix error message of interpreted FFI:CLINES form (M. Goffioul).
- Remove obsolete C::BUILD-ECL documentation (M. Goffioul).
- The conversion from ratio to float works now even if the
numerator/denominator
are themselves too large to fit a float.
- Fixnums and short-floats were compared using the "float" C type.
This led to
loss of precision and caused
(= (1+ (ceiling (rational -3.781832e7))) -3.781832e7) => T
- Keyword arguments in a type defined with DEFTYPE, for which a
default value
is not given, default to '*. Also the DEFTYPE form are enclosed in a
block
with the name of the type.
- The syntax of #\: can now be changed.
- Adjusting displaced bit-vectors failed to take the displace-offset
into
account.
- Variable SI::*GC-VERBOSE* controls whether ECL emits messages when
FASL
libraries are garbage colleced.
- Values of EQL specializers are now evaluated in the lexical
environment
in which the DEFMETHOD is enclosed. This makes it now possible to
write
(defmethod foo (x) (defmethod bar ((f (eql x)))))
- Fixes in the C code to comply with gcc 4.0.
* ANSI compatibility:
- Several functions that signaled type-errors did not set the right
values
on the field TYPE-ERROR-EXPECTED-TYPE. We now use the following
types:
* valid function names => (SATISFIES EXT:VALID-FUNCTION-NAME-P)
* proper list => PROPER-LIST = (OR (CONS T PROPER-LIST) NULL)
* positive fixnum => (INTEGER 0 MOST-POSITIVE-FIXNUM)
* nonnegative integer => (INTEGER 0 *)
* index in a seq => (INTEGER 0 L) where L is (1- (length
sequence))
- (COMPLEX *) is now recognized as valid type identifier by subtypep.
- TYPE-OF now returns more precise type names, so that if (TYPE-OF x)
= t1 and
(TYPEP x t2) = T then (SUBTYPEP t1 t2) = T.
- MAKE-PATHNAME now signals ordinary errors when the arguments do not
have
the required type, but signals a file error when it finds something
like
a wrong directory (i.e. '(:ABSOLUTE :UP)).
- Pathnames which contain :BACK in the directory, now print as
unreadable
objects, instead of signaling an error when printing.
- Declaration names cannot be used to define new type names and
viceversa.
- #\Space has constituent trait "invalid".
- DEFINE-SETF-EXPANDER encloses the form in an implicit block with the
name of
the SETF function.
* New features:
- Added function si:rmdir (M. Pasternacki)
- There are now specialized arrays for 32 or 64 bits data, depending
on the
size of words in the platform.
On 2005-08-12 12:48:35 -0400, "Juanjo" <····@arrakis.es> said:
> ECL 0.9g
> ========
>
> * Platforms:
>
> - Fixed the broken port for MacOSX. It should work with any release >=
> 10.2
>
> - Based on version 6.5 of Boehm-Weiser garbage collector, which fixes
> some
> problems related to the OSX port.
Fails on Mac OS X 10.4.2 thus:
gcc -c -I. -I/Users/raffaelc/Developer/ecl-0.9g/src/c
-I/Users/raffaelc/Developer/ecl-0.9g/src/h -I../h -g -O2 -fPIC
-fno-common -fstrict-aliasing -Ddarwin -o alloc_2.o alloc_2.c
/Users/raffaelc/Developer/ecl-0.9g/src/c/alloc_2.d:29:32: error:
gc/private/gc_priv.h: No such file or directory
/Users/raffaelc/Developer/ecl-0.9g/src/c/alloc_2.d: In function
'cl_alloc_object':
/Users/raffaelc/Developer/ecl-0.9g/src/c/alloc_2.d:120: warning:
assignment makes integer from pointer without a cast
/Users/raffaelc/Developer/ecl-0.9g/src/c/alloc_2.d: In function 'ecl_mark_env':
/Users/raffaelc/Developer/ecl-0.9g/src/c/alloc_2.d:248: error: 'ptr_t'
undeclared (first use in this function)
/Users/raffaelc/Developer/ecl-0.9g/src/c/alloc_2.d:248: error: (Each
undeclared identifier is reported only once
/Users/raffaelc/Developer/ecl-0.9g/src/c/alloc_2.d:248: error: for each
function it appears in.)
/Users/raffaelc/Developer/ecl-0.9g/src/c/alloc_2.d:248: error: parse
error before 'env'
/Users/raffaelc/Developer/ecl-0.9g/src/c/alloc_2.d:249: error: parse
error before 'env'
/Users/raffaelc/Developer/ecl-0.9g/src/c/alloc_2.d:252: error: parse
error before 'env'
/Users/raffaelc/Developer/ecl-0.9g/src/c/alloc_2.d:253: error: parse
error before 'env'
/Users/raffaelc/Developer/ecl-0.9g/src/c/alloc_2.d:256: error: parse
error before 'env'
/Users/raffaelc/Developer/ecl-0.9g/src/c/alloc_2.d:257: error: parse
error before 'env'
/Users/raffaelc/Developer/ecl-0.9g/src/c/alloc_2.d:277: error: parse
error before 'env'
/Users/raffaelc/Developer/ecl-0.9g/src/c/alloc_2.d: In function
'stacks_scanner':
/Users/raffaelc/Developer/ecl-0.9g/src/c/alloc_2.d:300: error: 'ptr_t'
undeclared (first use in this function)
/Users/raffaelc/Developer/ecl-0.9g/src/c/alloc_2.d:301: error: parse
error before 'cl_symbols'
make[2]: *** [alloc_2.o] Error 1
rm array.c symbol.c num_rand.c num_sfun.c cmpaux.c list.c unixsys.c
num_arith.c load.c string.c stacks.c hash.c main.c predicate.c
num_log.c unixint.c instance.c compiler.c character.c multival.c gfun.c
structure.c sequence.c ffi.c unixfsys.c reference.c time.c big.c
print.c backq.c format.c typespec.c num_co.c num_pred.c macros.c
alloc_2.c read.c error.c num_comp.c number.c pathname.c file.c
assignment.c cfun.c disassembler.c interpreter.c mapfun.c package.c
eval.c
make[1]: *** [libeclmin.a] Error 2
make: *** [all] Error 2
any hints of course very welcome.
regards
> Fails on Mac OS X 10.4.2 thus:
> gcc -c -I. -I/Users/raffaelc/Developer/ec l-0.9g/src/c
> -I/Users/raffaelc/Developer/ec l-0.9g/src/h -I../h -g -O2 -fPIC
> -fno-common -fstrict-aliasing -Ddarwin -o alloc_2.o alloc_2.c
> /Users/raffaelc/Developer/ecl- 0.9g/src/c/alloc_2.d:29:32: error:
> gc/private/gc_priv.h: No such file or directory
Are you trying to build it against a pre-installed version of the
Boehm-Weiser garbage collector? This error typically happens when one
has the GC preinstalled and ECL detects it and tries to use it, or when
you use --with-system-boehm=yes. Both procedures typically lead to a
failure because many software distributions do not install the
collector private headers gc_priv.h
If this is not the case, I would need a full log, the configuration
files (config.status, config.log, h/config.h) and the configuration
flags. Feel free to send these details to my private address shown
above and on the project page.
Juanjo
On 2005-08-13 11:04:42 -0400, "Juanjo" <····@arrakis.es> said:
> Are you trying to build it against a pre-installed version of the
> Boehm-Weiser garbage collector? This error typically happens when one
> has the GC preinstalled and ECL detects it and tries to use it, or when
> you use --with-system-boehm=yes. Both procedures typically lead to a
> failure because many software distributions do not install the
> collector private headers gc_priv.h
That was it.
./configure --enable-boehm=included
worked like a charm.
muchisimas gracias, JuanJo
Raffael
Juanjo wrote:
> Hi,
>
> just before I go on holidays I decided to pack all the latest
> improvements in the ECL source tree and make another 0.9 release. In
> case you find bugs or problems building it, please report it using the
> facilities in Source Forge (http://www.sourceforge.net/projects/ecls).
> Otherwise, enjoy it!
>
> Juanjo
Looks great, I tested it this weekend. It compiled greatly under mingw
on windows. I am new to ECL, and what I liked very much is the ability
to create a standalone exe file, when only ecl.dll must be distributed
with the program.
I couldn't figure out whether a user can break the execution of read
form without breaking the whole interpreter, as CTRL+C does. In CLISP,
it works fine.
Do you have plans for unicode support? It would be nice to have all
those format, string-upcase, and other facilities for native encodings.
What about strange behavior,
I had performed the following test:
============================================================
> (defvar *hash* (make-hash-table :size 10000 :test 'equal))
*HASH*
> ;; we'll call this **1**
(time (loop
for x from 0 to 10000
for key-name = (format nil "key-~a" x)
for key-value = (format nil "value-~a" x) do
(setf (gethash key-name *hash*) key-value)))
real time : 18.000 secs
run time : 18.000 secs
NIL
> ;; Trying to get inexistent keys
(time (dotimes (x 10000) (setf a (gethash x *hash*))))
real time : 0.000 secs
run time : 0.000 secs
NIL
> ;; setting 10000 items
(time (dotimes (x 10000) (setf (gethash x *hash*) x)))
real time : 14.000 secs
run time : 14.000 secs
NIL
> ;; getting 10000 items
(time (dotimes (x 10000) (setf a (gethash x *hash*))))
real time : 6.000 secs
run time : 6.000 secs
NIL
>
============================================================
Slow, right?
But what's amusing, when I do the same without form called **1** (see
above), the results are:
============================================================
> (defvar *hash* (make-hash-table :size 10000 :test 'equal))
*HASH*
> (time (dotimes (x 10000) (setf a (gethash x *hash*))))
real time : 0.000 secs
run time : 0.000 secs
NIL
> (time (dotimes (x 10000) (setf (gethash x *hash*) x)))
real time : 1.000 secs
run time : 1.000 secs
NIL
> (time (dotimes (x 10000) (setf a (gethash x *hash*))))
real time : 0.000 secs
run time : 0.000 secs
NIL
> (time (dotimes (x 10000) (setf (gethash (+ x 10000) *hash*) x)))
real time : 0.000 secs
run time : 0.000 secs
NIL
>
============================================================
Looks rather surprising.
FORMAT is at least stabilly slow:
;; 8 sec on ECL, 1.9 sec on CLISP (uncompiled)
(time (dotimes (x 10000) (format nil "~a" x)))
But it would be very interesting to know what happens to hashes. Maybe
it is due to keys that are strings?
Also I noticed some strange behavior of TIME macro under win32 -- it
always prints the integer number of seconds. Maybe the cause of error is
windows time() function.
I remember the similar situation when I used the following workaround:
#include <time.h>
#include <wtypes.h>
static time_t initial_time = 0; /* 0 means uninitialized */
static DWORD initial_tickcount;
double gettimeofday() {
double result;
if (initial_time == 0) {
initial_tickcount = GetTickCount();
initial_time = time(NULL);
result = initial_time;
} else {
result = initial_time + (GetTickCount() - initial_tickcount) * 1e-3;
}
return result;
}
It doesn't help to get the system time with precision better than one
second, but helps to measure the difference between two moments:
double t = gettimeofday();
int res = fib(29);
printf("result %d was computed in %f seconds.", res, gettimeofday()-t);
By the way, in fibonacci test compiled ECL has outperformed GCL and
compiled CLISP. OCaml is on the way. Congratulations!
Revzala Haelmic wrote:
> I couldn't figure out whether a user can break the execution of read
> form without breaking the whole interpreter, as CTRL+C does. In CLISP,
> it works fine.
Could you please send me an email detailing what you mean by breaking
the interpreter? I mean, the precise steps and what you would expect to
happen.
> Do you have plans for unicode support? It would be nice to have all
> those format, string-upcase, and other facilities for native encodings.
This is definitely doable, but requires time which I am now devoting to
other issues of higher priority, such as improving the stability of the
compiler and the overall speed.
> What about strange behavior,
> I had performed the following test:
> [... hash tables manipulation...]
> Looks rather surprising.
It is not surprising. What happens is that your hash table is mostly
full with strings that have more or less the same hash key. This means
that when GETHASH wants too look for a particular object, it ends most
of the time looking across the hash. Maybe ECL is a bit conservative on
the way it increases the size of hash tables, maybe the hash key
generator can be improved (There is code for crc32 hashes in the source
tree, uncommented due to speed issues). Incidentally, ECL uses SBCL's
hash algorithm for strings.
> Also I noticed some strange behavior of TIME macro under win32 -- it
> always prints the integer number of seconds. Maybe the cause of error is
> windows time() function.
Indeed the problem is with Windows's time() function not following the
standard.
> I remember the similar situation when I used the following workaround:
I take note.
> By the way, in fibonacci test compiled ECL has outperformed GCL and
> compiled CLISP. OCaml is on the way. Congratulations!
Let us not enter the performance war, please :-) CLISP's compiled code
is compiled to bytecodes and it outperforms typically ECL's own
bytecodes compiler, which is much much simpler (albeit rather fast).
Besides, there is lots of room for improvement in the code generation
routines of ECL, regarding type propagation and unboxing of different
data types.
But I am happy that the overall speed and features of ECL satisfy you.
Thanks for such a supportive message!
Juanjo
<····@arrakis.es> wrote:
> Incidentally, ECL uses SBCL's hash algorithm for strings.
Looks to me like it's using the old SBCL algorithm. We've been using the
one-at-a-time-hash from <http://burtleburtle.net/bob/hash/doobs.html>
for about 1.5 years now. It's a little bit slower, but the improvement
in hashing quality more than made up for it (for example compilation
speed improved by about 10% thanks to the change).
--
Juho Snellman
"Premature profiling is the root of all evil."