POV-Ray : Newsgroups : povray.off-topic : More Haskell fanning Server Time
30 Jul 2024 06:31:39 EDT (-0400)
  More Haskell fanning (Message 14 to 23 of 53)  
<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>
From: Darren New
Subject: Re: More Haskell fanning
Date: 15 May 2011 12:41:36
Message: <4dd00240$1@news.povray.org>
On 5/15/2011 3:22, Warp wrote:
> which was to properly handle C bitfields.

Given that C doesn't define what order bit fields go in, that seems like a 
tall order. You can't technically do that from assembler, either. :-)

Otherwise, it would seem pretty easy to write Haskell code (or any other 
language that handles integer math) to just use masks and multiplies and 
divides.

-- 
Darren New, San Diego CA, USA (PST)
   "Coding without comments is like
    driving without turn signals."


Post a reply to this message

From: Orchid XP v8
Subject: Re: More Haskell fanning
Date: 15 May 2011 13:23:45
Message: <4dd00c21$1@news.povray.org>
On 15/05/2011 05:41 PM, Darren New wrote:
> On 5/15/2011 3:22, Warp wrote:
>> which was to properly handle C bitfields.
>
> Given that C doesn't define what order bit fields go in, that seems like
> a tall order. You can't technically do that from assembler, either. :-)
>
> Otherwise, it would seem pretty easy to write Haskell code (or any other
> language that handles integer math) to just use masks and multiplies and
> divides.

There's a Haskell standard library that offers all the usual bit-level 
operators, so it's not like you have to multiply by 2 when what you 
really want is a left-shift.

-- 
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*


Post a reply to this message

From: Orchid XP v8
Subject: Re: More Haskell fanning
Date: 15 May 2011 13:26:35
Message: <4dd00ccb$1@news.povray.org>
On 15/05/2011 11:22 AM, Warp wrote:
> Orchid XP v8<voi### [at] devnull>  wrote:
>> I'm fairly sure I posted one in the other group a while back. Heck, I
>> even got qsort() from stdlib.h to work arbitrary Haskell data types,
>> just because Warp said it wasn't possible.
>
>    While calling C's qsort() from Haskell is impressive, you still failed
> to demonstrate the next challenge, which was to properly handle C bitfields.

I thought the next level was setjmp()?

> So there's still potentially something that Haskell cannot do with C... :P

If it's really that hard, ask C to do it, and call C from Haskell.

For that matter, C can't access [non-trivial] Haskell data either. If 
your C program wants to, say, access the 7th element of a Haskell list, 
it has to call Haskell and ask Haskell to fetch it and return something 
simple enough for C to comprehend. (The 7th element might not *exist* 
yet, for example...)

-- 
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*


Post a reply to this message

From: Orchid XP v8
Subject: Re: More Haskell fanning
Date: 15 May 2011 13:27:39
Message: <4dd00d0b$1@news.povray.org>
>> Argument from verbosity is seldom a good argument in programming.
>> Just because something is shorter doesn't necessarily mean it's better.
>
> I would say in this case it is, because all the extra stuff is just
> verbiage. It obscures the algorithm you're actually interested in, which
> is to make a new list where each element is the old list with 'bar'
> applied to it. All the stuff with the iterator and the types and all is
> just junk you have to repeat wherever you need to do this.

A far more relevant objection would be "how often does Haskell let you 
do less work?"

-- 
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*


Post a reply to this message

From: Invisible
Subject: Re: More Haskell fanning
Date: 16 May 2011 04:06:33
Message: <4dd0db09$1@news.povray.org>
>> foreign import stdcall "windows.h PostMessageW"
>> postMessage :: HWND -> WindowMessage -> WPARAM -> LPARAM -> IO LRESULT
>
> Oh yea. Very nice, yes. Amazing how many of the pre-C# languages made
> such a thing so tedious.

Hey, our language is *great*! Why would you ever want to call anything else?

>> How this actually finds the necessary code to execute, I have no idea.
>
> That's why they call it "the registry".

Well, no. See, if you call a Win32 function, it just works. If you call 
a function that you wrote yourself, you have to tell the linker to link 
the corresponding object code.

As I understand it, calling Win32 works by calling a C stub function 
which does the necessary machine code magic to actually invoke the 
Windows kernel, whatever that may be. But I don't see anywhere where 
this gets linked in...

>> You cannot access Haskell data from C at all. You can access C data from
>> Haskell if you're careful.
>
> OK. That's what I figured. I couldn't imagine how C was getting to lazy
> data easily.

You *can* do it of course, but it'll probably break with the next 
release of the compiler, so nobody does it. Instead, you write Haskell 
stub functions to fetch whatever item of data you want, and call that 
from C. (Or just design the program the other way around.)

I'm unsure how much runtime overhead is involved in calling between C 
and Haskell.

>> You can also build Haskell DLLs. I have no idea how that works...
>>
>> Speaking of which, GHC now supports compiling each Haskell library as
>> a DLL,
>> rather than linking them all statically. Unfortunately, this is broken
>> out-of-the-box. If you compile this way, you have to manually find all
>> the
>> DLLs your program requires and move them into the search path, because
>> the
>> GHC installer doesn't do this for you. Oops!
>
> That's why they call it the registry. :-)

The general opinion among Haskell developers is that Windows is "that 
evil platform that we shouldn't have to support". In particular, DLLs 
and the registry are both regarded as being impossibly complex to use, 
and to be avoided to the maximum extent possible.

Which is a bit like developing software for Linux and insisting that 
everybody should avoid using Bash.

>> Wouldn't converting one gigabyte of data to a new format online take
>> just as long as reloading it from disk?
>
> And yes, it would take just as long, but you don't have to do it all at
> once. You can be servicing requests, and reformatting data while you're
> not servicing requests.

OK, fair enough.

>> I'm not seeing why you would need to do this with cold code update
>> either.
>> You only need to shut down the processes related to the thing you're
>> actually changing.
>
> Then you have a bunch of different processes on the same machine
> fighting over resources. Sending messages between them means you now
> have a bunch of context switches, etc.

I don't follow.

>>> You can also convert things slowly, using the old data in the new code
>>> until all the old code is gone, then slowly work thru the data (perhaps
>>> updating it each time it's touched) to the new format.
>>
>> This is an unavoidable requirement which *must* be met if you want
>> distributed processing. Otherwise upgrading the system requires
>> stopping the
>> entire distributed network.
>
> Yep. And that's why building a big system like this with static
> type-erased data is more difficult than dynamic tagged data.

...which is why the Haskell implementation is using dynamic tagged data.

>> No, this is the fundamental problem with a small proof-of-concept
>> implementation exploring whether it's even slightly possible to do this.
>> Obviously the current implementation does not yet provide everything
>> necessary for production use. Nobody is claiming it does.
>
> Sure. I'm just not sure they've proved the concept if they can't handle
> that. :-)

Can't handle it _yet_. They have concrete plans for how they would 
implement it, they just haven't yet.

>> What is needed - and the documentation makes plain that the
>> implementors are
>> quite aware of this - is some way of varifying that the identifiers
>> you send
>> actually refer to the same thing. I don't actually know how Erlang
>> manages
>> to do this;
>
> Dynamic typing. :-)

That's not an answer. Haskell is typing values sent over the wire 
dynamically too. That doesn't automatically solve the problem.

There are two things to check: data structure type names and function 
names. The Erlang answer seems to be:

1. Make no attempt to verify whether data structures match at all. If 
the old code excepts data in one format and the new version expects data 
in an almost identical yet slightly different format, when the new code 
fires up it will just crash due to the data mismatch. Unless you 
specifically tested for this and wrote lots of code to make it work.

(By contrast, Haskell might potentially be able to distinguish the old 
type and the new type at the type level, if the structure of the type 
has actually changed, and issue a compile-time warning.)

2. I have literally no idea how Erlang sends functions over the wire. I 
had assumed it just sends the VM executable code over the wire. 
Obviously that only works if you're running on a VM. Haskell isn't. 
(There *is* a VM, but it's fairly slow, and has various other gotchas.) 
Haskell is sending the function name over the wire, but that only works 
if the name means the same thing at the other end.

In both cases, it looks like you need a name plus some kind of version 
number, or maybe a hash of a description or something, to distinguish 
things that the programmer has assigned identical names to...


Post a reply to this message

From: Darren New
Subject: Re: More Haskell fanning
Date: 16 May 2011 15:18:47
Message: <4dd17897@news.povray.org>
On 5/16/2011 1:06, Invisible wrote:
> Well, no. See, if you call a Win32 function, it just works. If you call a
> function that you wrote yourself, you have to tell the linker to link the
> corresponding object code.

Unless you register it, I expect.

> As I understand it, calling Win32 works by calling a C stub function which
> does the necessary machine code magic to actually invoke the Windows kernel,
> whatever that may be. But I don't see anywhere where this gets linked in...

It's entirely possible the declaration itself generates that code, isn't it? 
I'm pretty sure that's how it works in C#: you say "C# XYZ(i) calls 
C-languge PDQ with a (short) parameter" and the compiler generates an XYZ 
function that casts its argument to a short and jumps to the PDQ function, 
basically.

> the compiler, so nobody does it. Instead, you write Haskell stub functions

Yep. Kind of like calling C++ from C.

> Which is a bit like developing software for Linux and insisting that
> everybody should avoid using Bash.

Yep. More like developing distributed programs for Linux and deciding that 
sockets are too hard to use.

>>> I'm not seeing why you would need to do this with cold code update
>>> either.
>>> You only need to shut down the processes related to the thing you're
>>> actually changing.
>>
>> Then you have a bunch of different processes on the same machine
>> fighting over resources. Sending messages between them means you now
>> have a bunch of context switches, etc.
>
> I don't follow.

It's less efficient to have the kernel scheduler scheduling the different 
processes than to have the Erlang-specific scheduler doing it. That's why 
people make 100,000 erlang tasks in one process and doing the same in Linux 
will bring the kernel to its knees, if not run you out of memory.

>> Yep. And that's why building a big system like this with static
>> type-erased data is more difficult than dynamic tagged data.
>
> ...which is why the Haskell implementation is using dynamic tagged data.

Yep. And that loses a lot of the benefits of the static typing right there.

> Can't handle it _yet_. They have concrete plans for how they would implement
> it, they just haven't yet.

Fair enough. I look forward to seeing what they come up with.

> 1. Make no attempt to verify whether data structures match at all. If the
> old code excepts data in one format and the new version expects data in an
> almost identical yet slightly different format, when the new code fires up
> it will just crash due to the data mismatch. Unless you specifically tested
> for this and wrote lots of code to make it work.

Right.

Actually, even worse, in Erlang, the likelihood is that you just leave the 
mismatched message in the buffer, which then grows until it crashes the 
whole machine with no obvious reason. One of the poorly thought-out designs 
there, methinks.

> (By contrast, Haskell might potentially be able to distinguish the old type
> and the new type at the type level, if the structure of the type has
> actually changed, and issue a compile-time warning.)

This assumes you know at compile time what types the other side is using, 
which also isn't always true. :-)

> 2. I have literally no idea how Erlang sends functions over the wire.

It's out in the erldocs somewhere, but I can't find it after five minutes of 
looking around. They specify the wire format of everything, including that.

> assumed it just sends the VM executable code over the wire.

Given that I can write a function on an x86 machine and ship it over to a 
program running on a Sparc that has been running since before I bought the 
x86 machine, yah, I'd say there's some sort of virtual code being 
transfered. :-)

> In both cases, it looks like you need a name plus some kind of version
> number, or maybe a hash of a description or something, to distinguish things
> that the programmer has assigned identical names to...

It depends on whether you're sending a function or the name of the function, 
really.

-- 
Darren New, San Diego CA, USA (PST)
   "Coding without comments is like
    driving without turn signals."


Post a reply to this message

From: Invisible
Subject: Re: More Haskell fanning
Date: 17 May 2011 04:07:38
Message: <4dd22cca$1@news.povray.org>
On 16/05/2011 20:18, Darren New wrote:
> On 5/16/2011 1:06, Invisible wrote:
>> Well, no. See, if you call a Win32 function, it just works. If you call a
>> function that you wrote yourself, you have to tell the linker to link the
>> corresponding object code.
>
> Unless you register it, I expect.

Well, no, what I'm saying is that if you call a function that's defined 
in (say) windows.h, the linker somehow "finds" it. But if you wrote some 
C source code of your own, you have to tell the linker to link in the 
object code or it complains it can't find it.

It makes sense that you have to tell the linker where to find your own 
code. What I can't figure out is how it somehow "knows" when a function 
is from the Win32 API and magically finds it.

(The answer is probably something like "GHC automatically includes the 
Win32 files at link time".)

>> As I understand it, calling Win32 works by calling a C stub function
>> which
>> does the necessary machine code magic to actually invoke the Windows
>> kernel,
>> whatever that may be. But I don't see anywhere where this gets linked
>> in...
>
> It's entirely possible the declaration itself generates that code, isn't
> it? I'm pretty sure that's how it works in C#: you say "C# XYZ(i) calls
> C-languge PDQ with a (short) parameter" and the compiler generates an
> XYZ function that casts its argument to a short and jumps to the PDQ
> function, basically.

If I do a "foreign import", the Haskell compiler generates a Haskell 
function which calls the corresponding C function. Which is fine if 
you're statically linking the C code into your binary. But you don't 
link the Windows kernel into your application, do you? It does some 
weird magic with processor rings and code gates to enter kernel mode to 
run the code.

I'm no expert, but as I say, I was under the impression that the usual 
way to access a DLL is to link in a small C stub which defines the code 
necessary to dynamically find and execute the exported functions from 
the DLL.

>> Which is a bit like developing software for Linux and insisting that
>> everybody should avoid using Bash.
>
> Yep. More like developing distributed programs for Linux and deciding
> that sockets are too hard to use.

LOL! Yeah...

Seriously. Everybody talks about "hey, it's cool. Oh, except on Windows, 
where we have to solve DLL Hell. But hey, who actually uses Windows?"

Personally, I thought "DLL hell" went away about 10 years ago...

>>>> I'm not seeing why you would need to do this with cold code update
>>>> either.
>>>> You only need to shut down the processes related to the thing you're
>>>> actually changing.
>>>
>>> Then you have a bunch of different processes on the same machine
>>> fighting over resources. Sending messages between them means you now
>>> have a bunch of context switches, etc.
>>
>> I don't follow.
>
> It's less efficient to have the kernel scheduler scheduling the
> different processes than to have the Erlang-specific scheduler doing it.
> That's why people make 100,000 erlang tasks in one process and doing the
> same in Linux will bring the kernel to its knees, if not run you out of
> memory.

Right. So all you're saying is that OS processes are heavier than Erlang 
processes.

One thing Erlang can do (and Haskell can't, easily) is that because 
Erlang is a VM, you can have several unrelated Erlang applications 
running on the same VM. But to run multiple Haskell applications, you 
would have to have multiple copies of the Haskell runtime in action. 
Which, as you say, isn't something you want to do too much of.

>>> Yep. And that's why building a big system like this with static
>>> type-erased data is more difficult than dynamic tagged data.
>>
>> ...which is why the Haskell implementation is using dynamic tagged data.
>
> Yep. And that loses a lot of the benefits of the static typing right there.

*sigh* This old argument again.

Yes, the entire program is statically typed, but this one tiny part 
where you have to do a simple runtime type check automatically 
COMPLETELY DESTROYS EVERY SINGLE ADVANTAGE OF STATIC TYPING!

>> Can't handle it _yet_. They have concrete plans for how they would
>> implement it, they just haven't yet.
>
> Fair enough. I look forward to seeing what they come up with.

I look forward to seeing whether they ever finish it.

(I lose count of how many projects targeting Haskell at the GPU have 
been started. The number of them which produced a production-grade end 
product is zero.)

>> 1. Make no attempt to verify whether data structures match at all.
>
> Right.
>
> Actually, even worse, in Erlang, the likelihood is that you just leave
> the mismatched message in the buffer, which then grows until it crashes
> the whole machine with no obvious reason. One of the poorly thought-out
> designs there, methinks.

I'll say!

Basically you need to manually make sure you send a version number at 
the start of your message exchange, or something like that, and make 
sure that all servers and clients you write can handle all versions of 
the protocol.

Or design the protocol so that it never needs to change. (Which is not 
infeasible if you can send code as part of the protocol I suppose...)

>> (By contrast, Haskell might potentially be able to distinguish the old
>> type
>> and the new type at the type level, if the structure of the type has
>> actually changed, and issue a compile-time warning.)
>
> This assumes you know at compile time what types the other side is
> using, which also isn't always true. :-)

Not really. When you compile v1, you assume that the other side will be 
v1 as well. When you compile v2, the compiler checks what you changed, 
and warns you if you don't explicitly handle the v1 data (unless it's 
identical).

>> 2. I have literally no idea how Erlang sends functions over the wire.
>
> It's out in the erldocs somewhere, but I can't find it after five
> minutes of looking around. They specify the wire format of everything,
> including that.

Yeah, I figured.

The Haskell implementation has a potential advantage in that you can 
specify precisely how to serialise stuff if you want to. (Usually to 
send a more compact representation by leaving off data which can be 
recomputed at the other side, making use of the special structure of the 
data to skip parts of it, etc.) Of course, the bit that tells the other 
side who the message is for and what type it contains isn't open to 
negotiation. ;-)

>> assumed it just sends the VM executable code over the wire.
>
> Given that I can write a function on an x86 machine and ship it over to
> a program running on a Sparc that has been running since before I bought
> the x86 machine, yah, I'd say there's some sort of virtual code being
> transfered. :-)

And yet, that would seem rather heavy compared to just sending a 
function name (or rather, a *unique* function identifier), so perhaps 
Erlang actually does it that way like Haskell is doing. Or maybe it only 
sends the code if the other side doesn't already have it or something.

Come to think of it, I'm still figuring out how it manages to send atoms...

>> In both cases, it looks like you need a name plus some kind of version
>> number, or maybe a hash of a description or something, to distinguish
>> things
>> that the programmer has assigned identical names to...
>
> It depends on whether you're sending a function or the name of the
> function, really.

Well, we're sending type names too, which give you the same problem. 
(And sending a type definition doesn't help, because we still need to 
figure out whether they're *meant* to be the same type or not.)


Post a reply to this message

From: Darren New
Subject: Re: More Haskell fanning
Date: 17 May 2011 11:02:38
Message: <4dd28e0e@news.povray.org>
On 5/17/2011 1:07, Invisible wrote:
>> Unless you register it, I expect.
>
> Well, no, what I'm saying is that if you call a function that's defined in
> (say) windows.h, the linker somehow "finds" it.

Right. It's probably in the C runtime.

> But if you wrote some C
> source code of your own, you have to tell the linker to link in the object
> code or it complains it can't find it.

Right. Unless you register it. Then the linker looks up the code in the 
registry and links it against the file that the registry says the code is 
in. That's what the registry is for, and why it's called a registry.

You may need to make it a COM DLL first to register it; I don't remember the 
exact details any more.

> (The answer is probably something like "GHC automatically includes the Win32
> files at link time".)

That's my guess.

> If I do a "foreign import", the Haskell compiler generates a Haskell
> function which calls the corresponding C function. Which is fine if you're
> statically linking the C code into your binary. But you don't link the
> Windows kernel into your application, do you? It does some weird magic with
> processor rings and code gates to enter kernel mode to run the code.

In every system I've ever used, the "weird magic" is in a linker file that 
always gets loaded. For example, msvcrt.dll (Microsoft visual C run time) 
for Windows, glib for GCC under Linux, etc.

> I'm no expert, but as I say, I was under the impression that the usual way
> to access a DLL is to link in a small C stub which defines the code
> necessary to dynamically find and execute the exported functions from the DLL.

Or branch to a jump table that the loader fills in with addresses from the 
DLL when it loads the DLL, which it loads based on the headers of the program.

Most systems do almost all of this automatically specifically because C 
doesn't have any standard syntax for doing this. I suspect if 
dynamically-loaded code was the norm in C from the beginning, much less 
would be automated by the OS's loader.

> Personally, I thought "DLL hell" went away about 10 years ago...

Yes, pretty much.

> Right. So all you're saying is that OS processes are heavier than Erlang
> processes.

Well, much heavier than Linux or Windows processes. By many, many orders of 
magnitude. There are OSes where processes are very light, like Singularity, 
Mach, AmigaOS, etc. Generally what you hear referred to as a "microkernel" 
is a kernel where processes are so lightweight that you can afford to put 
each device driver and file system in its own process.

> One thing Erlang can do (and Haskell can't, easily) is that because Erlang
> is a VM, you can have several unrelated Erlang applications running on the
> same VM.

Yes. Indeed, the whole point of the VM is to be a virtual machine, so the 
idea of an "application" is a user-level construct, not something built into 
the language.  (In much the same way that a "login" is a user-level 
construct in UNIX/Linux, whereas in most other OSes, it's an OS-level 
construct.)

> Yes, the entire program is statically typed, but this one tiny part where
> you have to do a simple runtime type check automatically COMPLETELY DESTROYS
> EVERY SINGLE ADVANTAGE OF STATIC TYPING!

I didn't say that. I said it loses a lot of the benefits, where "benefits" 
are "guarantees" in my mind.

Now, in this particular case, it probably is doing enough work in the 
connected set of processes that converting from dynamic to static typing is 
worthwhile. In the discussions we were having before, I was talking about 
things like web pages, that almost never do any significant processing on 
their own at the server, so statically typing a web page where you're 
translating dynamically typed SQL results into HTML doesn't really help to 
have static typing. I.e., when it's not one tiny part but rather a majority 
of the program, it's worse.

> Basically you need to manually make sure you send a version number at the
> start of your message exchange, or something like that, and make sure that
> all servers and clients you write can handle all versions of the protocol.

Or you just check the types and do the right thing with them. Of course, 
knowing what the right thing is can be difficult. E.g., if you have been 
working with 2D longitude/latitude, and the new version needs altitude also, 
you could have all the places that take a 2-element tuple start also working 
with a 3-element tuple and asking how many elements it has, then start 
generating 3-element tuples. The number of elements in the tuple can serve 
as your version number.

> Or design the protocol so that it never needs to change. (Which is not
> infeasible if you can send code as part of the protocol I suppose...)

Well, they handle it by letting you upgrade the code.

> Not really. When you compile v1, you assume that the other side will be v1
> as well. When you compile v2, the compiler checks what you changed, and
> warns you if you don't explicitly handle the v1 data (unless it's identical).

That's fair. It would be interesting to see how that's specified.

> The Haskell implementation has a potential advantage in that you can specify
> precisely how to serialise stuff if you want to.

You just do that in code with Erlang. I.e., you write your own serializer, 
or you send a message to a local agent that then sends the message to the 
remote agent that has only what you want.

> And yet, that would seem rather heavy compared to just sending a function
> name (or rather, a *unique* function identifier),

Not all functions have names. For the functions that have names, I believe 
you just send the fully-qualified name of the function. (And since function 
names are atoms, the actual text of the function name is cached after the 
first time, so you don't have to send more than "the 37'th function I've 
sent you" next time.)

If you send a lambda, I believe it sends the bytecode. There may be caching 
involved there too, but I don't remember.

I was too awed by the landmines in the data format to remember the other 
details.

> Come to think of it, I'm still figuring out how it manages to send atoms...

It sends them as text, the first time.

-- 
Darren New, San Diego CA, USA (PST)
   "Coding without comments is like
    driving without turn signals."


Post a reply to this message

From: Darren New
Subject: Re: More Haskell fanning
Date: 17 May 2011 11:19:46
Message: <4dd29212$1@news.povray.org>
More erlang fanning:

The protocol between the deamons:

http://www.erlang.org/doc/apps/erts/erl_dist_protocol.html

The protocol between the individual actors:

http://www.erlang.org/doc/apps/erts/erl_ext_dist.html

You want to look at 8.21 and 8.22.  It seems the code doesn't ship, since 
logically the function can't really be constructed at runtime. Instead, it's 
a reference into the BEAM file (where a BEAM is like a java jar).

Because of course "external term format" is exactly what anyone would google 
for to find that.  I'm also rather amused that altho Erlang has wonderfully 
powerful expressions for parsing byte streams, they used ASCII art with 
ambiguous textual descriptions to describe the format of the stuff on the 
wire instead of giving you the Erlang expression that would parse it 
unambiguously.

-- 
Darren New, San Diego CA, USA (PST)
   "Coding without comments is like
    driving without turn signals."


Post a reply to this message

From: Invisible
Subject: Re: More Haskell fanning
Date: 17 May 2011 11:22:28
Message: <4dd292b4$1@news.povray.org>
>> But if you wrote some C
>> source code of your own, you have to tell the linker to link in the
>> object
>> code or it complains it can't find it.
>
> Right. Unless you register it. Then the linker looks up the code in the
> registry and links it against the file that the registry says the code
> is in. That's what the registry is for, and why it's called a registry.
>
> You may need to make it a COM DLL first to register it; I don't remember
> the exact details any more.

I was under the impression that the registry is *only* for dynamic 
linking, and has nothing to do with static linking [which is what I'm 
talking about here].

> In every system I've ever used, the "weird magic" is in a linker file
> that always gets loaded. For example, msvcrt.dll (Microsoft visual C run
> time) for Windows, glib for GCC under Linux, etc.

Right. That's probably it...

> Most systems do almost all of this automatically specifically because C
> doesn't have any standard syntax for doing this. I suspect if
> dynamically-loaded code was the norm in C from the beginning, much less
> would be automated by the OS's loader.

On the other hand, the main advantage of C is that almost nothing is 
built-in, which means that everything can be changed... ;-)

>> Personally, I thought "DLL hell" went away about 10 years ago...
>
> Yes, pretty much.

This is from the people who actually had to ask "does Windows actually 
support letting multiple processes open the same disk file at once?"

>> One thing Erlang can do (and Haskell can't, easily) is that because
>> Erlang
>> is a VM, you can have several unrelated Erlang applications running on
>> the
>> same VM.
>
> Yes. Indeed, the whole point of the VM is to be a virtual machine, so
> the idea of an "application" is a user-level construct, not something
> built into the language.

Fair enough.

Question: Does that mean that one process can produce so much garbage 
that it forces endless GC cycles, slowing other unrelated processes 
down? Or does the VM partition memory on a per-process basis or something?

>> Yes, the entire program is statically typed, but this one tiny part where
>> you have to do a simple runtime type check automatically COMPLETELY
>> DESTROYS EVERY SINGLE ADVANTAGE OF STATIC TYPING!
>
> I didn't say that. I said it loses a lot of the benefits, where
> "benefits" are "guarantees" in my mind.
>
> Now, in this particular case, it probably is doing enough work in the
> connected set of processes that converting from dynamic to static typing
> is worthwhile. In the discussions we were having before, I was talking
> about things like web pages, that almost never do any significant
> processing on their own at the server, so statically typing a web page
> where you're translating dynamically typed SQL results into HTML doesn't
> really help to have static typing. I.e., when it's not one tiny part but
> rather a majority of the program, it's worse.
>
>> Basically you need to manually make sure you send a version number at the
>> start of your message exchange, or something like that, and make sure
>> that
>> all servers and clients you write can handle all versions of the
>> protocol.
>
> Or you just check the types and do the right thing with them.

Well yeah, but if you're trying to use a mere textual "name" to decide 
what type something is, you need a version number or something to go 
with the name, to make it unique.

What Erlang is doing is considering any two types to be "identical" if 
they have the same *structure*. That wouldn't do for Haskell; consider, 
for example, how a PortID and a ThreadID are both 32-bit signed 
integers, but are considered utterly different, incompatible types.

[Of course, TRWTF is that it's *signed*...]

>> Or design the protocol so that it never needs to change. (Which is not
>> infeasible if you can send code as part of the protocol I suppose...)
>
> Well, they handle it by letting you upgrade the code.

You can upgrade the code, but unless you upgrade it all at once, both 
versions need to speak the same wire protocol.

>> Not really. When you compile v1, you assume that the other side will
>> be v1
>> as well. When you compile v2, the compiler checks what you changed, and
>> warns you if you don't explicitly handle the v1 data (unless it's
>> identical).
>
> That's fair. It would be interesting to see how that's specified.

I guess we sit back and see if they ever release anything...

>> The Haskell implementation has a potential advantage in that you can
>> specify
>> precisely how to serialise stuff if you want to.
>
> You just do that in code with Erlang. I.e., you write your own
> serializer, or you send a message to a local agent that then sends the
> message to the remote agent that has only what you want.

Yeah, I guess that works too.

Presumably Erlang allows you to serialise cyclic data structures, which 
is notoriously hard for a pure functional language.

>> And yet, that would seem rather heavy compared to just sending a function
>> name (or rather, a *unique* function identifier),
>
> Not all functions have names. For the functions that have names, I
> believe you just send the fully-qualified name of the function.

Only works if foo/3 on node X is the same thing as foo/3 on node Y. ;-)

> If you send a lambda, I believe it sends the bytecode. There may be
> caching involved there too, but I don't remember.
>
> I was too awed by the landmines in the data format to remember the other
> details.

I'll have to check it out sometime...

>> Come to think of it, I'm still figuring out how it manages to send
>> atoms...
>
> It sends them as text, the first time.

Oh, right. So atoms are *globally* unique, not unique to each node?


Post a reply to this message

<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.