D
Don Y
Hi James,
A translation of the Limbo code appears at the end. Expecting *me*
to come up with a C version that uses features THAT I DIDN'T KNOW
EXISTED as of a few hours ago would be as prepostrous as me asking
you to tell me why C's approach is better than a Limbo approach --
and expecting *you* to provide that Limbo example! (assuming you've
never seen Limbo code until the same point in this thread that *I*
Exactly. I have no interest in waiting for a C2011 implementation
greetings(
surname: string, # parameter of type "string"
children: list of (string, int) # a list of tuples each
# consisting of a string and an int
output: chan of string # communication channel named "output"
# that conveys strings
) {
# create a string by concatenating the two string constants
# with the string *variable* passed to the function as "surname"
# pass the resulting string out the channel named "output"
output <-= "Season's Greetings from the "
+ surname + " family!\n";
# as long as the "children" list is not empty...
while (children != nil) {
# extract one the first ("head") element from the "children"
# list assigning it's component values to "firstname" and "int"
# the presence of the ':' is a syntactic shortcut that allows
# the declaration of these variables to be deduced from the
# values assigned to them (i.e., we know children consists
# of (string, int) tuples so we know "firstname" is now declared
# as a string and "age" is an int. I.e., this just saves two
# lines declaring those types as
# firstname: string;
# age: int;
(firstname, age) := hd children;
# ':' tells you that description is of the same type as the
# rvalue -- a string (since the expression on the right is
# recognizable as a string). Set the description string
# variable to the concatenation of the "firstname" and "surname"
# strings -- with a constant string (whitespace) in the middle
description := firstname + " " + surname;
# tack on the parenthetical comment indicating the child's age
# note the use of '=' instead of ":=" -- since we have already
# declared description's type
description = description
+ " (" + age + " years old)";
# pass the "fullname" (grrr... should have been "description")
# string to the communication channel named "output"
output <-= fullname;
# assign the balance (everything beyond the "head") of the children
# list to the children list variable
children = tl children;
}
}
logging(
input: chan of string # communication channel named "input"
# that conveys 'strings'
) {
sys = load Sys Sys->PATH; # a variable that holds a reference to
# a module called Sys. Sys->PATH
# is a constant defined within that
# module indicating where it is
while (FOREVER) {
# text is a string (because it's type is derived from the
# rhs type -- which is "chan of string"
# It's value is assigned from the string fetched from the
# communication channel named "input"
text :=<- input;
# use the print() member of the module referenced by "sys"
# to print a string "somewhere" (i.e., like printf)
sys->print("%s\n", text)
}
}
job(surname: string,
children: list of (string, int) # you've seen this before...
) {
pipe: channel of string; # declare "pipe" to be a communication
# channel (should have been "chan") that
# conveys "string" data types.
# create a thread that executes the "logging" function (defined
# above). Pass it a communication channel that it will use to
# watch for incoming text
spawn logging(pipe);
# create a thread that executes the "greetings" function (defined
# above). Pass it the communication channel that it should use
# to interact with the "logging" function started above. Pass
# the surname and list of children's (names, ages) to that
# function (i.e., thread) so that it has some work to do.
spawn greetings(surname, children, pipe)
...
}
I.e., anything that doesn't say "chan" or "spawn" in the above
is "application" and unrelated to the tasking aspects of the
language.
That requires us to be able to correctly interpret Limbo code. You know
Limbo, I don't, and I suspect that such ignorance is fairly common here.
It should be incumbent on you, not us, to provide a translation.
A translation of the Limbo code appears at the end. Expecting *me*
to come up with a C version that uses features THAT I DIDN'T KNOW
EXISTED as of a few hours ago would be as prepostrous as me asking
you to tell me why C's approach is better than a Limbo approach --
and expecting *you* to provide that Limbo example! (assuming you've
never seen Limbo code until the same point in this thread that *I*
was informed of said:Even if I were familiar with Limbo, I'm not competent to provide a
counter-example, and never claimed to be. I've written highly parallel
code - a quarter century ago, using a non-conforming C compiler, a
highly idiosyncratic operating system, and a concept that I no longer
remember the name of that was significantly different from the concept
of threads.
I've written ordinary POSIX threaded code - but that was just for fun,
about two decades ago, and I never even got it running, because I had
more urgent work that I was actually being paid to do. I've only just
started familiarizing myself with C2011 threads; I'm not ready to write
anything using them.
Understood.
As the complainant, you should be competent to provide an example of the
problem you're complaining about - without such expertise the problem
could just be due to your lack of familiarity with the system. Not many
Exactly. I have no interest in waiting for a C2011 implementation
people are C2011 threading experts yet; I'd happily accept as relevant
an example using any other well-known threading system with a C
interface, such as POSIX threads. As I indicated above, I wouldn't be
competent to judge your example, but other people on this forum would
be; presumably including Ben Pfaff.
greetings(
surname: string, # parameter of type "string"
children: list of (string, int) # a list of tuples each
# consisting of a string and an int
output: chan of string # communication channel named "output"
# that conveys strings
) {
# create a string by concatenating the two string constants
# with the string *variable* passed to the function as "surname"
# pass the resulting string out the channel named "output"
output <-= "Season's Greetings from the "
+ surname + " family!\n";
# as long as the "children" list is not empty...
while (children != nil) {
# extract one the first ("head") element from the "children"
# list assigning it's component values to "firstname" and "int"
# the presence of the ':' is a syntactic shortcut that allows
# the declaration of these variables to be deduced from the
# values assigned to them (i.e., we know children consists
# of (string, int) tuples so we know "firstname" is now declared
# as a string and "age" is an int. I.e., this just saves two
# lines declaring those types as
# firstname: string;
# age: int;
(firstname, age) := hd children;
# ':' tells you that description is of the same type as the
# rvalue -- a string (since the expression on the right is
# recognizable as a string). Set the description string
# variable to the concatenation of the "firstname" and "surname"
# strings -- with a constant string (whitespace) in the middle
description := firstname + " " + surname;
# tack on the parenthetical comment indicating the child's age
# note the use of '=' instead of ":=" -- since we have already
# declared description's type
description = description
+ " (" + age + " years old)";
# pass the "fullname" (grrr... should have been "description")
# string to the communication channel named "output"
output <-= fullname;
# assign the balance (everything beyond the "head") of the children
# list to the children list variable
children = tl children;
}
}
logging(
input: chan of string # communication channel named "input"
# that conveys 'strings'
) {
sys = load Sys Sys->PATH; # a variable that holds a reference to
# a module called Sys. Sys->PATH
# is a constant defined within that
# module indicating where it is
while (FOREVER) {
# text is a string (because it's type is derived from the
# rhs type -- which is "chan of string"
# It's value is assigned from the string fetched from the
# communication channel named "input"
text :=<- input;
# use the print() member of the module referenced by "sys"
# to print a string "somewhere" (i.e., like printf)
sys->print("%s\n", text)
}
}
job(surname: string,
children: list of (string, int) # you've seen this before...
) {
pipe: channel of string; # declare "pipe" to be a communication
# channel (should have been "chan") that
# conveys "string" data types.
# create a thread that executes the "logging" function (defined
# above). Pass it a communication channel that it will use to
# watch for incoming text
spawn logging(pipe);
# create a thread that executes the "greetings" function (defined
# above). Pass it the communication channel that it should use
# to interact with the "logging" function started above. Pass
# the surname and list of children's (names, ages) to that
# function (i.e., thread) so that it has some work to do.
spawn greetings(surname, children, pipe)
...
}
I.e., anything that doesn't say "chan" or "spawn" in the above
is "application" and unrelated to the tasking aspects of the
language.