Error building crack-0.7.1 from source

10 views
Skip to first unread message

Bill Hart

unread,
Sep 15, 2013, 4:31:35 PM9/15/13
to crack-l...@googlegroups.com
Hi,

I hope this is the correct place to ask about build issues. I decided I wanted to try out crack-0.7.1 but I was unable to build it from source. I am building on Ubuntu 12.04 on an AMD x86_64 with gcc 4.7.3.

I took the latest LLVM 3.3 and built and installed that. (A similar problem occurred with LLVM 3.1.)

I downloaded crack-0.7.1. (A similar problem occurs with crack-0.7 and with the CMake build.)

I did

./configure
make

But I got the following error. Unfortunately, I have been unable to figure out what I'm doing wrong. Can you help?

builder/llvm/LLVMBuilder.cc: In member function 'virtual model::ResultExprPtr builder::mvll::LLVMBuilder::emitStrConst(model::Context&, model::StrConst*)':
builder/llvm/LLVMBuilder.cc:728:56: error: no matching function for call to 'llvm::GlobalVariable::GlobalVariable(llvm::Module&, llvm::Type*, bool, llvm::GlobalValue::LinkageTypes, llvm::Constant*&, std::basic_string<char>, int, bool)'
builder/llvm/LLVMBuilder.cc:728:56: note: candidates are:
In file included from /home/wbhart/anaconda/include/llvm/Module.h:19:0,
                 from builder/llvm/LLVMBuilder.cc:43:
/home/wbhart/anaconda/include/llvm/GlobalVariable.h:68:3: note: llvm::GlobalVariable::GlobalVariable(llvm::Module&, llvm::Type*, bool, llvm::GlobalValue::LinkageTypes, llvm::Constant*, const llvm::Twine&, llvm::GlobalVariable*, llvm::GlobalVariable::ThreadLocalMode, unsigned int)
/home/wbhart/anaconda/include/llvm/GlobalVariable.h:68:3: note:   no known conversion for argument 8 from 'bool' to 'llvm::GlobalVariable::ThreadLocalMode'
/home/wbhart/anaconda/include/llvm/GlobalVariable.h:63:3: note: llvm::GlobalVariable::GlobalVariable(llvm::Type*, bool, llvm::GlobalValue::LinkageTypes, llvm::Constant*, const llvm::Twine&, llvm::GlobalVariable::ThreadLocalMode, unsigned int)
/home/wbhart/anaconda/include/llvm/GlobalVariable.h:63:3: note:   candidate expects 7 arguments, 8 provided
/home/wbhart/anaconda/include/llvm/GlobalVariable.h:39:3: note: llvm::GlobalVariable::GlobalVariable(const llvm::GlobalVariable&)
/home/wbhart/anaconda/include/llvm/GlobalVariable.h:39:3: note:   candidate expects 1 argument, 8 provided
make[1]: *** [libCrackLang_la-LLVMBuilder.lo] Error 1
make[1]: Leaving directory `/home/wbhart/crack-0.7'
make: *** [all] Error 2

My autotools barfs on the latest mercurial clone of crack, so I wasn't able to build directly from the repository. I'd prefer to stick with a stable version anyway, if possible.

Bill.

Bill Hart

unread,
Sep 15, 2013, 4:36:08 PM9/15/13
to crack-l...@googlegroups.com
Oh dear, excuse me. Immediately after posting this, the problem became painfully obvious. It is clearly picking up an LLVM associated to some other project.

I don't know why it is looking there instead of the usual install location, but obviously I have something hanging around in my environment that I shouldn't. Sorry for the noise.

Bill.

Conrad Steenberg

unread,
Sep 15, 2013, 7:06:09 PM9/15/13
to crack-l...@googlegroups.com
Hi Bill,

FWIW, on Ubuntu 12.04 I use the llvm.org nightly repositories for 3.3,
which is stable at this point, despite the 'nightly' moniker.

I'd also encourage you to use the current development branch at
http://code.google.com/p/crack-language/ as there have been lots of
progress on the code since 0.71.

Cheers,
Conrad
> --
> You received this message because you are subscribed to the Google
> Groups "crack-lang-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to crack-lang-de...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.


Michael Muller

unread,
Sep 16, 2013, 9:11:57 AM9/16/13
to Conrad Steenberg, goodwi...@googlemail.com, crack-l...@googlegroups.com

Also, if you're using 0.7.1, you will need llvm 3.1 (and a patched one, at
that). As Conrad has said, if you want the latest LLVM you'll need the
mercurial trunk.
=============================================================================
michaelMuller = mmu...@enduden.com | http://www.mindhog.net/~mmuller
-----------------------------------------------------------------------------
Lokah Samasta Sukhino Bhavantu - May all beings everywhere be happy and free.
And may my own thoughts and actions contribute to that happiness and freedom.
=============================================================================

Bill Hart

unread,
Sep 16, 2013, 12:29:41 PM9/16/13
to crack-l...@googlegroups.com
Hi, 

Thanks, I managed to get it going with LLVM 3.1. The messages I posted appear with LLVM 3.2, as I am sure you already realised.

I have to say, I am loving Crack programming so far. I hooked it up to the fmpz module from flint (http://flintlib.org) using primitive bindings to give myself bignums (it uses GMP for anything over 1 limb and machine longs otherwise) and coded up some simple factorial and fibonacci number generators and am quite impressed that I can get very close to the speed of the native GMP factorial and fibonacci functions (using some easy but not stupid algorithms of course). So, that confirms that the FFI is working really well.

I'm also loving the operator overloading.

I don't know if you are interested in user feedback at this point, but here are some observations I have already made. Any suggestions are welcome.

* I had an issue using a C string function via the FFI. It returns a C string which the user is required to clean up. I was unclear on whether Crack would know to clean it up if I placed that string inside a Crack Buffer or something similar.

* I also had some difficulties figuring out how to convert such a C string into a Crack string. The documentation seems to indicate that strings in Crack should be viewed as immutable.

* I was not able to understand the documentation on the Formatter protocol and on ManagedBuffers. I don't really know what either of these do or how to use them. This is probably just a concept which is familiar to other programming language designers, but not to me.

* Some of the Writer examples in the docs don't seem to compile.

* I am really missing tuples and tuple unpacking. Are there plans to add them? (I know the former can be created using a class.)

* I am really missing dependent types, e.g. types parameterised by integers, strings and symbols. (C++ does the former, D allows strings, for example.) Are there any plans to add these?

* I wasn't clear on how to create and precompile my own crack modules. I guess this is not implemented yet, but planned?

* strcpy seems to no longer be in runtime but is referred to as such in the docs.

* I was disappointed that Crack was unable to infer types used in templated classes. E.g. if I create class Pair[FirstType, SecondType], it seems that I cannot do Pair(12, 14) and have it infer that FirstType is int and SecondType is int (or whatever 12 and 14 are). Are there plans to add this?

That's all I can think of for now. Anyway, I had a lot of fun last night playing with Crack-lang. 

Did I see somewhere that someone is planning a repl?

Bill.

Michael Muller

unread,
Sep 16, 2013, 12:50:53 PM9/16/13
to Bill Hart, crack-l...@googlegroups.com

Bill Hart wrote:
> Hi,
>
> Thanks, I managed to get it going with LLVM 3.1. The messages I posted
> appear with LLVM 3.2, as I am sure you already realised.
>
> I have to say, I am loving Crack programming so far. I hooked it up to the
> fmpz module from flint (http://flintlib.org) using primitive bindings to
> give myself bignums (it uses GMP for anything over 1 limb and machine longs
> otherwise) and coded up some simple factorial and fibonacci number
> generators and am quite impressed that I can get very close to the speed of
> the native GMP factorial and fibonacci functions (using some easy but not
> stupid algorithms of course). So, that confirms that the FFI is working
> really well.
>
> I'm also loving the operator overloading.
>
> I don't know if you are interested in user feedback at this point, but here
> are some observations I have already made. Any suggestions are welcome.
>
> * I had an issue using a C string function via the FFI. It returns a C
> string which the user is required to clean up. I was unclear on whether
> Crack would know to clean it up if I placed that string inside a Crack
> Buffer or something similar.

That depends on the buffer. See lib/crack/lang.crk

>
> * I also had some difficulties figuring out how to convert such a C string
> into a Crack string. The documentation seems to indicate that strings in
> Crack should be viewed as immutable.

That depends. If you have a null-terminated string 's', you can do String(s).
This will copy the buffer. You can also use String(s, num_bytes, false) to
create a copy of the backing string or String(s, num_bytes, true) if you want
the new object to take ownership of the original memory (and release it with
free()).

>
> * I was not able to understand the documentation on the Formatter protocol
> and on ManagedBuffers. I don't really know what either of these do or how
> to use them. This is probably just a concept which is familiar to other
> programming language designers, but not to me.
>
> * Some of the Writer examples in the docs don't seem to compile.
>
> * I am really missing tuples and tuple unpacking. Are there plans to add
> them? (I know the former can be created using a class.)

Not as such, but I've long considered how best to add anonymous structures to
the language which would serve a similar function. My current thinking is
something along the lines of this:

struct[String name, int val] getItem() { return {'foo', 100}; }

item := getItem();
cout `$(item.name)\n`;

But this is far from definite.

>
> * I am really missing dependent types, e.g. types parameterised by
> integers, strings and symbols. (C++ does the former, D allows strings, for
> example.) Are there any plans to add these?

Not at this time, but I'd be interested to hear your use case for them.

>
> * I wasn't clear on how to create and precompile my own crack modules. I
> guess this is not implemented yet, but planned?

You can't do this at the module level. You can run "crackc" on a script to
package the script and all of its dependencies into a single executable.

The main thing I've been working on over the past year has been module
caching. Basically, the first time you compile a module, the executor creates
cache files for that module (an LLVM bitcode file and a Crack meta-data file).
From then on, the cache files are imported instead of recompiling the module
(as long as its source and dependencies haven't changed).

Caching isn't quite the same as pre-compiling. You could distribute the cache
files, but there's no guarantee that a user would be able to use them the way
they want, in the long-run there may be many cache file formats, and in fact
LLVM bit-code currently isn't platform indepdendent. The distribution mode
for Crack modules really is intended to be the module source.

>
> * strcpy seems to no longer be in runtime but is referred to as such in the
> docs.

That's odd, it seems to still be there for me.

import crack.runtime strcpy;
strcpy(byteptr(0), byteptr(0));

>
> * I was disappointed that Crack was unable to infer types used in templated
> classes. E.g. if I create class Pair[FirstType, SecondType], it seems that
> I cannot do Pair(12, 14) and have it infer that FirstType is int and
> SecondType is int (or whatever 12 and 14 are). Are there plans to add this?

Nothing concrete, but I agree that this would be useful. It's a complicated
problem that I haven't given much thought to.

>
> That's all I can think of for now. Anyway, I had a lot of fun last night
> playing with Crack-lang.
>
> Did I see somewhere that someone is planning a repl?

Someone worked on one a while ago, but I had some issues with some of the
implemementation details and we were unable to come to a resolution on them
before he moved on.

I'd like very much to see it happen, but it needs an owner with the necessary
skills, motivation and patience to put up with the rest of us ;-)

I'm glad to hear you enjoyed the language!
And thanks for the feedback, I'll try to fix some of the breakage in the docs.
Government is not reason, it is not eloquence; it is force. Like fire, it
is a dangerous servant and a fearsome master. - George Washington
=============================================================================

Conrad Steenberg

unread,
Sep 16, 2013, 1:53:24 PM9/16/13
to crack-l...@googlegroups.com
Hi Bill,

I also stumbled upon Crack looking to use it for numerics :-)

We don't really use the dynamic FFI much, as it is usually more robust
to create a static (precompiled) wrapper, Crack has a great wrapper
generator that I use all the time.

Have a look at opt/_fluidsynth.crk for a short example. If the library
is easily wrapped, you basically just write all the method specs you
want bound, using Crack syntax.

Top create the C++ file to be compiled, do in the crack download
directory:
crack opt/_fluidsynth.crk

Assuming you installed Crack with 'make install', you can compile this
with:
g++ -I/usr/local/include/crack-0.7/crack -fPIC -shared -o
opt/_fluidsynth.so

Some more below:

On Mon, 2013-09-16 at 17:29 +0100, Bill Hart wrote:
> Hi,
>
>
> Thanks, I managed to get it going with LLVM 3.1. The messages I posted
> appear with LLVM 3.2, as I am sure you already realised.
>
>
> I have to say, I am loving Crack programming so far. I hooked it up to
> the fmpz module from flint (http://flintlib.org) using primitive
> bindings to give myself bignums (it uses GMP for anything over 1 limb
> and machine longs otherwise) and coded up some simple factorial and
> fibonacci number generators and am quite impressed that I can get very
> close to the speed of the native GMP factorial and fibonacci functions
> (using some easy but not stupid algorithms of course). So, that
> confirms that the FFI is working really well.
>
>
> I'm also loving the operator overloading.
>
>
> I don't know if you are interested in user feedback at this point, but
> here are some observations I have already made. Any suggestions are
> welcome.
>
>
> * I had an issue using a C string function via the FFI. It returns a C
> string which the user is required to clean up. I was unclear on
> whether Crack would know to clean it up if I placed that string inside
> a Crack Buffer or something similar.

You can create a CString object that owns the underlying buffer (C
string) and frees it when it gets destroyed:

import crack.lang CString;
cs := CString(cstring, true);

For lack of better documentation, have a look at lib/crack/lang.crk

>
>
> * I also had some difficulties figuring out how to convert such a C
> string into a Crack string. The documentation seems to indicate that
> strings in Crack should be viewed as immutable.

>
>
> * I was not able to understand the documentation on the Formatter
> protocol and on ManagedBuffers. I don't really know what either of
> these do or how to use them. This is probably just a concept which is
> familiar to other programming language designers, but not to me.
>
>
> * Some of the Writer examples in the docs don't seem to compile.
>
>
> * I am really missing tuples and tuple unpacking. Are there plans to
> add them? (I know the former can be created using a class.)
>
>
> * I am really missing dependent types, e.g. types parameterised by
> integers, strings and symbols. (C++ does the former, D allows strings,
> for example.) Are there any plans to add these?
>
>
> * I wasn't clear on how to create and precompile my own crack modules.
> I guess this is not implemented yet, but planned?
Modules imported into your code are compiled at the same time as the
rest of your code. Which is what makes compilation kinda slow at the
moment. Michael is working on caching compiled modules for JIT
compilation at the moment, but this won't be used for AOT compilation
AFAIK.

Btw, we are usually at #crack-lang on freenode.

Cheers,
Conrad
> from it, send an email to crack-lang-dev
> +unsub...@googlegroups.com.
> > For more options, visit
> https://groups.google.com/groups/opt_out.
> >
>
>
>
=============================================================================
> michaelMuller = mmu...@enduden.com |
> http://www.mindhog.net/~mmuller
>
-----------------------------------------------------------------------------
> Lokah Samasta Sukhino Bhavantu - May all beings everywhere be
> happy and free.
> And may my own thoughts and actions contribute to that
> happiness and freedom.
>
=============================================================================
>
>

Bill Hart

unread,
Sep 16, 2013, 5:25:37 PM9/16/13
to crack-l...@googlegroups.com



On 16 September 2013 17:50, Michael Muller <mmu...@enduden.com> wrote:

<SNIP>
 

>
> * I also had some difficulties figuring out how to convert such a C string
> into a Crack string. The documentation seems to indicate that strings in
> Crack should be viewed as immutable.

That depends.  If you have a null-terminated string 's', you can do String(s).
This will copy the buffer.  You can also use String(s, num_bytes, false) to
create a copy of the backing string or String(s, num_bytes, true) if you want
the new object to take ownership of the original memory (and release it with
free()).

As a general follow-up question, is there a list of all the prototypes of functions available in the standard libraries somewhere? So far I only found this:

 

>
> * I was not able to understand the documentation on the Formatter protocol
> and on ManagedBuffers. I don't really know what either of these do or how
> to use them. This is probably just a concept which is familiar to other
> programming language designers, but not to me.
>
> * Some of the Writer examples in the docs don't seem to compile.
>
> * I am really missing tuples and tuple unpacking. Are there plans to add
> them? (I know the former can be created using a class.)

Not as such, but I've long considered how best to add anonymous structures to
the language which would serve a similar function.  My current thinking is
something along the lines of this:

   struct[String name, int val] getItem() { return {'foo', 100}; }

   item := getItem();
   cout `$(item.name)\n`;

But this is far from definite.

Theoretically, anonymous structs are the same thing I guess. But the power of having the compiler unpack the struct for you is certainly a very nice power to have, and that is doubly nice when the compiler can optimise away the actual struct itself so that no memory allocation actually occurs, e.g. in other languages:

(a, b, c) := (1, 'text', 2.3);

For the example you have above, giving names to the fields seems to negate the benefits that tuples have. For example, why not:

struct[String, int] getItem() { return {'foo', 100}; }

(name, val) := getitem();
cout `$(name)\n`;

Since functions require return types to be specified, the compiler can always determine the types here, so this doesn't create any hard inference problems. 

Admittedly, your example requires some additional fuss if you do things my way, e.g.

item := getitem();

then either:

cout `$(item[0])\n`;

which I don't prefer. Or

cout `$component(item, 0)\n`;

And I have to admit that I like your solution better for this use case. 

Anyway, I'll have to wait and see what you eventually do.


>
> * I am really missing dependent types, e.g. types parameterised by
> integers, strings and symbols. (C++ does the former, D allows strings, for
> example.) Are there any plans to add these?

Not at this time, but I'd be interested to hear your use case for them.

This is complicated and I've had great difficulty explaining this to other people if they are not computer algebraists. I will not consider it controversial that parameterisation of types on integers is important. C++, Julia, D and many other languages have that and it has infinitely many uses. So I will restrict my answer to other kinds of "symbols".

The short answer is that it is useful for performance reasons.

The long answer is to consider the following example: suppose you are designing a computer algebra system and you want to offer all kinds of polynomials: univariate, multivariate, over various base rings: integers, other polynomial rings, integers mod n, the real numbers, etc. Moreover, you want to allow the user to build up arbitrary polynomial rings of their own invention, not just sticking with some preprogrammed rings you have provided (this is extremely common in practice for computer algebraists, by the way).

In general, to specify a univariate polynomial ring and a polynomial as an element of that ring, you need a number of pieces of information.

1) The base ring, R say, e.g. the integers, another polynomial ring, a matrix ring, whatever.

2) A variable, e.g. x, y, z, etc.

3) Some actual coefficient data, including a coefficient array, a length (degree), maybe an amount of space allocated. 

We might denote a polynomial ring by R[x] where R is the base ring and x is the variable. We think of this as the type. 

A polynomial element of this ring might be of the form p := a*x^2 + b*x + c for example, where a, b, c are elements of the ring R (i.e. they are of type R).

Now it is uncontroversial that (1) is type information.  In a programming language, R is a type. This is important because you cannot add polynomials over the integers with polynomials over integers mod 23 for example and have that mean something. So a polynomial over R and a polynomial over S, for example, are not compatible in any way. The base rings have to be the same type. It's a type error to try and add two such polynomials, otherwise. 

We can argue about whether R is a *parameter* type or not, but it is a type, and Crack can handle this fine right now.

It is also uncontroversial that (3) is runtime data. 

The controversy happens at (2). Is 'x' part of the *type* (the polynomial ring), or part of the runtime data (the polynomial object), or both?

If it is part of the runtime data, then every time you add two actual polynomial objects together, you need to check that they have the same variable.

For example, if p := 2*x^2 + 3*x + 7 and q := 3y^4 - 2*y + 6, what if the user asked for p + q? You need to exclude that, (or otherwise do something about it).

Clearly p is in ZZ['x'] and q is in ZZ['y'], and they are not compatible (unless you coerce both to ZZ['x', 'y'] of course). 

Now checking that the variables are the same can either be done at runtime or at compile time. 

It goes without saying that it is more efficient if done at compile time. It also saves the programmer a whole load of work because the compiler will do the type checking automatically.

Now, admittedly making the variables, 'x', 'y', etc., parameters of the type, rather than runtime information is only useful if the user is treating the language itself as a computer algebra system (i.e. computer algebra as an internal, rather than external DSL). Clearly the compiler has no way of comparing types that depend on *runtime* parameters. It can only check types that depend on *compile time* parameters. But this is the case I have in mind (especially if the language eventually has a REPL where the distinction is slightly blurred anyway).

The most important thing is that generic programming like this takes an enormous runtime hit essentially equivalent to using a dynamic instead of statically typed language, unless there are dependent types. It's quite common in computer algebra systems for there to be a factor of 100 slowdown as soon as arithmetic requires generic rings as opposed to specialised implementations of particular preprogrammed rings, precisely because of this problem.

Dependent types depending on static compile time values (such as the variable strings 'x' or 'y', etc.) fix this problem, so long as the user specifies the rings they are working with at compile time so that the compiler can statically decide if two (dependent) types are the same or not (the compiler first checks that the parameters hash to the same thing, etc....)

I hope the above is a clear explanation. Typical responses I get are usually along the following lines:

"Well, what kind of polynomials are you trying to add together? When I want to add two polynomials over the integers for example, I use floating point coefficients and just set up two arrays with floating point entries and then just use function x.y.z in our standard library to 'add' the arrays together. Have you tried this? I can't see why adding two polynomials together should be hard for you."


>
> * I wasn't clear on how to create and precompile my own crack modules. I
> guess this is not implemented yet, but planned?

You can't do this at the module level.  You can run "crackc" on a script to
package the script and all of its dependencies into a single executable.

The main thing I've been working on over the past year has been module
caching.  Basically, the first time you compile a module, the executor creates
cache files for that module (an LLVM bitcode file and a Crack meta-data file).
From then on, the cache files are imported instead of recompiling the module
(as long as its source and dependencies haven't changed).

Ok. If this works out, then it solves the problem I guess.
 

Caching isn't quite the same as pre-compiling.  You could distribute the cache
files, but there's no guarantee that a user would be able to use them the way
they want, in the long-run there may be many cache file formats, and in fact
LLVM bit-code currently isn't platform indepdendent.  The distribution mode
for Crack modules really is intended to be the module source.

>
> * strcpy seems to no longer be in runtime but is referred to as such in the
> docs.

That's odd, it seems to still be there for me.

  import crack.runtime strcpy;
  strcpy(byteptr(0), byteptr(0));

I'm sorry. Perhaps I became confused with strlen, which I was also using last night.
 

>
> * I was disappointed that Crack was unable to infer types used in templated
> classes. E.g. if I create class Pair[FirstType, SecondType], it seems that
> I cannot do Pair(12, 14) and have it infer that FirstType is int and
> SecondType is int (or whatever 12 and 14 are). Are there plans to add this?

Nothing concrete, but I agree that this would be useful.  It's a complicated
problem that I haven't given much thought to.

>
> That's all I can think of for now. Anyway, I had a lot of fun last night
> playing with Crack-lang.
>
> Did I see somewhere that someone is planning a repl?

Someone worked on one a while ago, but I had some issues with some of the
implemementation details and we were unable to come to a resolution on them
before he moved on.

I'd like very much to see it happen, but it needs an owner with the necessary
skills, motivation and patience to put up with the rest of us ;-)

I have the skills. But I wouldn't take it on.

Repl's impose additional constraints. In particular, the user will mistype things and want to change them. This requires some ability to 'unload' definitions that have already been compiled and to recover from a much greater range of errors.

I notice Crack also requires forward references instead of only compiling function definitions at their first application (by which point the other needed functions have presumably also been entered). That's a requirement which looks more awkward when entering stuff via a repl.

There's also further requirements with regard to lexer/parser recovery and evaluation of expressions, textual representations of things that need displaying, introspection, IO issues, error reporting, especially with regard to line numbers of source code, recovery from segfaults, etc, etc. Some of this can be separated from the rest of the compiler, especially if the functionality can be placed in a repl namespace, but in short, repl's are highly disruptive and intrusive. 

On the other hand, Crack is in the enviable position of being able to offer a repl which would be almost as fast as compiled code. It's a possibility that LLVM opens up which most other systems cannot provide.


I'm glad to hear you enjoyed the language!
And thanks for the feedback, I'll try to fix some of the breakage in the docs.


It's a never ending and thankless task. But for what it is worth, thanks for your efforts.

Bill.

Michael Muller

unread,
Sep 18, 2013, 10:35:48 AM9/18/13
to Bill Hart, crack-l...@googlegroups.com

Bill Hart wrote:
> On 16 September 2013 17:50, Michael Muller <mmu...@enduden.com> wrote:
>
> <SNIP>
>
>
> >
> > >
> > > * I also had some difficulties figuring out how to convert such a C
> > string
> > > into a Crack string. The documentation seems to indicate that strings in
> > > Crack should be viewed as immutable.
> >
> > That depends. If you have a null-terminated string 's', you can do
> > String(s).
> > This will copy the buffer. You can also use String(s, num_bytes, false) to
> > create a copy of the backing string or String(s, num_bytes, true) if you
> > want
> > the new object to take ownership of the original memory (and release it
> > with
> > free()).
> >
>
> As a general follow-up question, is there a list of all the prototypes of
> functions available in the standard libraries somewhere? So far I only
> found this:
>
> http://www.mindhog.net/~mmuller/projects/crack/Manual-0.7.html

Not at this time, I'm afraid our best reference is the source.

It has been a long-standing goal to autogenerate docs from the source,
doxygen/javadoc style. In fact, I'd like to build the neccessary support into
the parser.
> cout `$(item <http://item.name/>[0])\n`;
>
> which I don't prefer. Or
>
> cout `$component(item, 0)\n`;
>
> And I have to admit that I like your solution better for this use case.
>
> Anyway, I'll have to wait and see what you eventually do.

There's definitely something to be said for being able to store aggregates on
the stack instead of allocating a new object on the heap. That's something
I'd like to see, but it's orthogonal to the question of multiple variable
assignment: we could also use this feature with anonymous structs.

I'm not generally opposed to multiple variable assignments, but anonymous
tuples have some problems, which is why python introduced named tuples:
os.stat(file).st_mode is preferrable to os.stat(file)[7]

Ultimately, the reason I don't think we're likely to adopt multiple variable
assignments is the same reason we don't allow wildcard imports: they are a
barrier to module writers preserving compatibility. For example, if I have a
function that returns (a, b) and I want to add 'c' to that aggregate, I can't
do it without breaking everyone who is doing "(a, b) = myFunction()"
Wow, thank you for explaining all of this: unfortunately, it's more than I've
had a chance to digest. You're talking about a lot of maths that I haven't
worked with (at least not recently enough to remember them). But I promise I
will dig through this more thoroughly at some point.
Only when a function is used prior to being defined. Crack does a single-pass
compile.
Those who do not understand Unix are condemned to reinvent it, poorly.
-- Henry Spencer
=============================================================================
Reply all
Reply to author
Forward
0 new messages