string(Integer)

22 vistas
Ir al primer mensaje no leído

Grégory Vanuxem

no leída,
20 mar 2024, 2:41:50 p.m.20 mar
para fricas...@googlegroups.com
Hello,

Do you happen to know why the declaration of string(Integer) is in
StringCategory and its definition in the String domain?
(STRINGIMAGE$Lisp)

That way if someone adds a domain, say, Foo, that has an Integer to
Foo coercion and exports a 'string' operation the interpreter will
choose the Foo one. It's a bit of a shame, isn't it? After all, the
Integer domain has operations that are totally unrelated to the
mathematical notion of integers, for example OpenMath stuff.

- Greg

Waldek Hebisch

no leída,
20 mar 2024, 5:28:28 p.m.20 mar
para fricas...@googlegroups.com
On Wed, Mar 20, 2024 at 07:41:11PM +0100, Grégory Vanuxem wrote:
> Hello,
>
> Do you happen to know why the declaration of string(Integer) is in
> StringCategory and its definition in the String domain?
> (STRINGIMAGE$Lisp)

'string' constructs a String and as all functions of similar sort
is defined in corresponding domain. As usual, 'string' is declared
in corresponding category, that is StringCategory

> That way if someone adds a domain, say, Foo, that has an Integer to
> Foo coercion and exports a 'string' operation the interpreter will
> choose the Foo one. It's a bit of a shame, isn't it?

Well, that is how Spad overloading works: if you have two ways
they should give the same result or you need to be more specific
(hide Foo, add explicit '$Integer' etc.). If Foo can be coerced
to Integer, then maybe 'string' in Foo is not needed at all.

Also, note that interpreter coercions are tuned to existing set
of domains. When you add new domains (or new operations to existing
domains) with current rules interpreter can make undesirable
choice. That is a shame, when adding exposed operations we need
to take into account what interpreter will do, or modify
interpreter to change its rules. Ideally there should be a
user level way to add or remove interpreter inference rules.

--
Waldek Hebisch

Grégory Vanuxem

no leída,
25 mar 2024, 7:12:20 a.m.25 mar
para fricas...@googlegroups.com
hello Waldek, hello folks,

Le mer. 20 mars 2024 à 22:28, Waldek Hebisch <de...@fricas.org> a écrit :
>
> On Wed, Mar 20, 2024 at 07:41:11PM +0100, Grégory Vanuxem wrote:
> > Hello,
> >
> > Do you happen to know why the declaration of string(Integer) is in
> > StringCategory and its definition in the String domain?
> > (STRINGIMAGE$Lisp)
>
> 'string' constructs a String and as all functions of similar sort
> is defined in corresponding domain. As usual, 'string' is declared
> in corresponding category, that is StringCategory

Yes, of course. I was just wondering why String(__Integer_) was
declared there instead of a generic declaration like:
string : % -> String

That way, like Symbol, it can be defined in the Integer domain and
thus avoid unexpected effects during interpreter coercion mechanisms.
I encountered this with other integer related domains like another
prime field domain, another integer mod domain... etc.

In fact, instead of declaring string : % -> String in those domains I
declare it at a 'Category' level and that solved this. To be more
precise, I do not ask for its implementation, having a way to obtain
an ASCII string representation of every Spad object would be handy I
find. Even string(Type) like string(Integer) => "Integer". I guess
this exists somewhere in Spad but I have not found where. A good
candidate to use it could be the 'error' function. There seems to be
no implicit rules to use this function and from memory I have seen an
error like "Not invertible". Franckly, imagine you have a lot of code
with integers, matrices etc. and you see this error. Euh... Not a
field? rectangular matrix? Singular maybe? And so on. Personally I
like to know the function who throws the error and more information
could be handy. For example string(%) could be of use. I only know the
'latex' function declared in SetCategory that resembles but it is a
typesetting function, not a simple string function.

,>
> > That way if someone adds a domain, say, Foo, that has an Integer to
> > Foo coercion and exports a 'string' operation the interpreter will
> > choose the Foo one. It's a bit of a shame, isn't it?
>
> Well, that is how Spad overloading works: if you have two ways
> they should give the same result or you need to be more specific
> (hide Foo, add explicit '$Integer' etc.). If Foo can be coerced
> to Integer, then maybe 'string' in Foo is not needed at all.

Yes, but from my point of view string(Integer) should not be
overloaded, it is up to the Integer domain author/programmer to handle
this coercion Integer -> String. There is 'convert@String' though, but
it uses 'string':
convert(x : %) : String == string(x pretend Integer)$String

>
> Also, note that interpreter coercions are tuned to existing set
> of domains. When you add new domains (or new operations to existing
> domains) with current rules interpreter can make undesirable
> choice. That is a shame, when adding exposed operations we need
> to take into account what interpreter will do, or modify
> interpreter to change its rules.

I totally agree.

> Ideally there should be a
> user level way to add or remove interpreter inference rules.

Ideally, yes.

- Greg


>
> --
> Waldek Hebisch
>
> --
> You received this message because you are subscribed to the Google Groups "FriCAS - computer algebra system" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to fricas-devel...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/fricas-devel/ZftU-WcPThCruCpy%40fricas.org.

Waldek Hebisch

no leída,
27 mar 2024, 9:50:59 p.m.27 mar
para fricas...@googlegroups.com
On Mon, Mar 25, 2024 at 12:11:42PM +0100, Grégory Vanuxem wrote:
> hello Waldek, hello folks,
>
> Le mer. 20 mars 2024 à 22:28, Waldek Hebisch <de...@fricas.org> a écrit :
> >
> > On Wed, Mar 20, 2024 at 07:41:11PM +0100, Grégory Vanuxem wrote:
> > > Hello,
> > >
> > > Do you happen to know why the declaration of string(Integer) is in
> > > StringCategory and its definition in the String domain?
> > > (STRINGIMAGE$Lisp)
> >
> > 'string' constructs a String and as all functions of similar sort
> > is defined in corresponding domain. As usual, 'string' is declared
> > in corresponding category, that is StringCategory
>
> Yes, of course. I was just wondering why String(__Integer_) was
> declared there instead of a generic declaration like:
> string : % -> String

Where would you like to put this declaration? Declaration without
implementation is problematic, as this would lead to errors at
runtime. So any more general declaration would need associated
implementation. By its very nature operation like 'string' is
specific to a domain.

>
> That way, like Symbol, it can be defined in the Integer domain and
> thus avoid unexpected effects during interpreter coercion mechanisms.
> I encountered this with other integer related domains like another
> prime field domain, another integer mod domain... etc.
>
> In fact, instead of declaring string : % -> String in those domains I
> declare it at a 'Category' level and that solved this. To be more
> precise, I do not ask for its implementation,

We try to have implementation for any declared function. Otherwise
we have code which compiles cleanly but fails at runtime. Most
users consider such behaviour to be a bug.

> having a way to obtain
> an ASCII string representation of every Spad object would be handy I
> find.

That if done as independent implementation would be a significant effort.
Now we could try to use Format1D and existing coercion to OutputForm
for this, but 'string' for Integer is special, because it used by
formating machinery. And there are domains without coercion to
OutputForm.

> Even string(Type) like string(Integer) => "Integer". I guess
> this exists somewhere in Spad but I have not found where.

Not in Spad. ATM this is done at Boot level.

> A good
> candidate to use it could be the 'error' function. There seems to be
> no implicit rules to use this function and from memory I have seen an
> error like "Not invertible". Franckly, imagine you have a lot of code
> with integers, matrices etc. and you see this error. Euh... Not a
> field? rectangular matrix? Singular maybe? And so on. Personally I
> like to know the function who throws the error

That is easy, we have things like

error "makeSketch: constant polynomial"

That is, include function name as part of error message.

> and more information
> could be handy. For example string(%) could be of use. I only know the
> 'latex' function declared in SetCategory that resembles but it is a
> typesetting function, not a simple string function.

Well, output goes via OutputForm. IMO main problem is that ATM
putting OutputForm in messages is clumsy. Compared to that things
like 'string' add IMO little value.
> ,>
> > > That way if someone adds a domain, say, Foo, that has an Integer to
> > > Foo coercion and exports a 'string' operation the interpreter will
> > > choose the Foo one. It's a bit of a shame, isn't it?
> >
> > Well, that is how Spad overloading works: if you have two ways
> > they should give the same result or you need to be more specific
> > (hide Foo, add explicit '$Integer' etc.). If Foo can be coerced
> > to Integer, then maybe 'string' in Foo is not needed at all.
>
> Yes, but from my point of view string(Integer) should not be
> overloaded, it is up to the Integer domain author/programmer to handle
> this coercion Integer -> String. There is 'convert@String' though, but
> it uses 'string':
> convert(x : %) : String == string(x pretend Integer)$String

Well, IMO big problem with 'convert' is that interpreter is too
eager to use it. And we really do not want interpreter to convert
things to strings and then report errors or worse do operation
on strings.

--
Waldek Hebisch

Ralf Hemmecke

no leída,
27 mar 2024, 10:15:48 p.m.27 mar
para fricas...@googlegroups.com
> That is easy, we have things like
>
> error "makeSketch: constant polynomial"
>
> That is, include function name as part of error message.

We should, maybe, more often use the two argument error function.

https://github.com/fricas/fricas/blob/master/src/algebra/error.spad#L47

Ralf

Waldek Hebisch

no leída,
27 mar 2024, 10:55:44 p.m.27 mar
para fricas...@googlegroups.com
Hmm, have you used them? Documentation say "callable from the system
interpreter". 'error' is built into Spad compiler and it is not
clear to me if you can call any other 'error'. Also, if you
managed to call them it is not clear if they would for as expected.

And finally, what is gain from giving function name as a separate
argument? AFAICS in Spad one needs to specify it anyway, so can be part
of error message.

--
Waldek Hebisch

Ralf Hemmecke

no leída,
28 mar 2024, 3:02:50 a.m.28 mar
para fricas...@googlegroups.com
On 3/28/24 03:55, Waldek Hebisch wrote:
> On Thu, Mar 28, 2024 at 03:15:46AM +0100, Ralf Hemmecke wrote:
>>> That is easy, we have things like
>>>
>>> error "makeSketch: constant polynomial"
>>>
>>> That is, include function name as part of error message.
>>
>> We should, maybe, more often use the two argument error function.
>>
>> https://github.com/fricas/fricas/blob/master/src/algebra/error.spad#L47
>
>>
> Hmm, have you used them?

Oh, true, I haven't.

> Documentation say "callable from the system interpreter". 'error' is
> built into Spad compiler...

Wow! I learnt something new. As I understand it, there are two

error: String -> Exit

functions, one builtin and one from ErrorFunctions. I wonder why you say
that calling

error("blah")$ErrorFunctions

in SPAD code might not work. The only strange calls I see are

throwPatternMsg(s, []$(List String))$Lisp

and

"exit" pretend Exit

but are they really problematic?

OK the answer to the above is not soo important to me, but I think Greg
is right that the builtin 'error' should automatically show the function
name in which it is called. Doesn't the compiler have all this information?

Such an improvement would really be great.

Ralf

Hill Strong

no leída,
28 mar 2024, 8:25:05 p.m.28 mar
para fricas...@googlegroups.com
On Thu, Mar 28, 2024 at 6:02 PM Ralf Hemmecke <ra...@hemmecke.org> wrote:


OK the answer to the above is not soo important to me, but I think Greg
is right that the builtin 'error' should automatically show the function
name in which it is called. Doesn't the compiler have all this information?

Such an improvement would really be great.

The compiler should have enough information to generate appropriate code for the builtin function error to be able to generate the domain/category/package specification as well as the function in which the builtin function is called as well as the relevant parameters used for the calling function. The code generation phase of the compiler should be able to generate relevant code that obtains all the necessary runtime information and display it. It is far better to get more information relating to the error than less. More helpful information reduces the time it takes to work out what has gone wrong and what you need to fix that specific error.

Yes, I do understand just how much work is involved in doing this and yes many people do not see the need for this level of work until it comes and bites them on the posterior. If that information is not there, users quickly get frustrated (especially new users) and it is always good to have new users picking up your systems and becoming enthusiastic proponents of the system.

If you go through all calls to error in the FriCAS code base, the current error messages are often quite cryptic and of little help in analysing any problem that does arise. Since error messages are not the normal mode of operation, any system generated code for enhancing error messages will not/should not affect any of the normal code being run and should not affect how fast the normal mode code runs.

If this is left to the programmer to adjust the various error messages throughout the code base, this will be a very large task.



Ralf


--
You received this message because you are subscribed to the Google Groups "FriCAS - computer algebra system" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fricas-devel...@googlegroups.com.

Waldek Hebisch

no leída,
29 mar 2024, 7:43:21 p.m.29 mar
para fricas...@googlegroups.com
On Fri, Mar 29, 2024 at 11:24:59AM +1100, Hill Strong wrote:
> On Thu, Mar 28, 2024 at 6:02 PM Ralf Hemmecke <ra...@hemmecke.org> wrote:
>
> >
> >
> > OK the answer to the above is not soo important to me, but I think Greg
> > is right that the builtin 'error' should automatically show the function
> > name in which it is called. Doesn't the compiler have all this information?
> >
> > Such an improvement would really be great.
> >
>
> The compiler should have enough information to generate appropriate code
> for the builtin function error to be able to generate the
> domain/category/package specification as well as the function in which the
> builtin function is called as well as the relevant parameters used for the
> calling function.

Compiler knows function name and constructor name. Note however
that FriCAS types are parametrized, and type parameter are known
only at runtime. Of course, compiler knows how to access type
parameters. Also note that functions can be overloaded, so
to know which function was called you need its signature (types
of return value and parameters).

> The code generation phase of the compiler should be able
> to generate relevant code that obtains all the necessary runtime
> information and display it. It is far better to get more information
> relating to the error than less.

It depends. Actually in FriCAS I rarely met situations where
information can not be displayed. Problem usually is that
there is way too much info and it is hard to find relevant
part. For example, trace generates a lot of info, but if
one traces "popular" constructor one gets a lot of irrelevant
stuff before important things happen.

And for debugging errors I normally look at backtrace. This
means that for reproducible errors I get way more info that
is reasonable to put into error message. Main drawback of
backtrace is that it works at Lisp level, so info is unreadable
to ordinary FriCAS user. At least using sbcl it is possible
to have user handler for backtrace, so in principle we could
print this info in more convenient way. But that is some
work to do at lowest level in FrICAS. I consider this important,
but other things for me have higher priority. And other folks
have their own priorites. In volunteer open source project telling
other prople to do some work usually is useless: if a person
can and want to do something he/she would do it anyway.
And if a person can not or does not want to do something,
then talk is useless.

> More helpful information reduces the time
> it takes to work out what has gone wrong and what you need to fix that
> specific error.
>
> Yes, I do understand just how much work is involved in doing this and yes
> many people do not see the need for this level of work until it comes and
> bites them on the posterior. If that information is not there, users
> quickly get frustrated (especially new users) and it is always good to have
> new users picking up your systems and becoming enthusiastic proponents of
> the system.
>
> If you go through all calls to error in the FriCAS code base, the current
> error messages are often quite cryptic and of little help in analysing any
> problem that does arise. Since error messages are not the normal mode of
> operation, any system generated code for enhancing error messages will
> not/should not affect any of the normal code being run and should not
> affect how fast the normal mode code runs.
>
> If this is left to the programmer to adjust the various error messages
> throughout the code base, this will be a very large task.

Well, concerning "cryptic error messages", let us look at recent
example posted by Ralf. We got:

>> System error:
The variable $$$ is unbound.

If you consider this carefully, this contains useful information.
First 'System error' tells you that error was detected at lowest
level (by Lisp system in this case). And "The variable $$$ is unbound."
tells you exactly what the problem is: code attempted to access
variable named '$$$' but such variable does not exist at this
time ("unbound" in Lisp terminology).

Of course, ordinary users may consider this cryptic, but IMO the
real trouble was that there was no apparent connection with user
input: from user point of view there was a sequence of commands
that executed OK at command line, but failed inside function body.

I am familiar with FriCAS code and I recently wrote RootSimplification
package that triggered the trouble so I was able to guess part of
explanation. But let us pretend that a developer tries to solve
this starting from "frist principles". First thing to do is to
write

)set break break

After that we get one extra piece of info:

(SB-EVAL::GET-VARIABLE $$$ #<SB-EVAL::ENV {10035A8D23}>)

which may look cryptic, but is the actual Lisp code that failed.
And this confirms that trouble is due to access to '$$$'.
Next thing is get backtrace. Backtrace may be long, so normally
one want only part of it. This time

backtrace 50

(which requires 50 positins) is right thing, but one knows this
only after solving tho problem. Normal way is to look at smaller
part and request bigger if needed. What we see in the backtrace?
First is seqence of calls, starting at

25: (|RootSimplification|)

RootSimplification is a constructor name and this means call which
initializes it. We see:

22: (|INFORM;interpret;%A;9| (SEQ (LET |eI| (|Expression| |Integer|)) (LET |a| (|::| (QUOTE |a|) |eI|)) (LET |b| (|::| (QUOTE |b|) |eI|)) (LET |c| (|::| (QUOTE |c|) |eI|)) (LET |r| (|::| (QUOTE |r|) |eI|)) (LET |e| (|::| (QUOTE |e|) |eI|)) (+ (+ (* (* # #) (^ |r| 2)) (* (+ # #) |r|)) (+ (* (+ # #) (^ |e| 4)) (* (* # |b|) (^ |e| 3))))) #<unavailable argument>)
23: (|RSIMP;str_to_expr| "eI := Expression(Integer); ...

Which means that 'str_to_expr' in RootSimplification called 'interpret'
which is call from Spad code to interpreter. So we now know that
error happended when intepreter was evaluating code passed as a
string from 'str_to_expr'. There are several calls which are not
interesting, relevant one is:

9: (|evalFormMkValue| #(^ NIL NIL NIL ((|totalArgs| . 2) (|argumentNumber| . 2) (|callingFunction| . *))) (SPADCALL (QUOTE ((1 #S(SPAD_KERNEL :OP # :ARG NIL :NEST 1) (1 . #1=#)) . #1#)) 2 (ELT $$$ 4)) (|Expression| (|Integer|)))
^^^^^^^^^^^

Here we see piece of Lisp code generated by FriCAS which tries to
access '$$$'. So we can guess that this code is wrong, and we need
to find out which part/what is responsible for this code. One
hint is part before initialization of RootSimplification (after all
we know that on command line initialization of RootSimplification
works without error). We have:

42: (|compileDeclaredMap| |nicer| ...

which means that interpreter is compiling 'nicer' and needs to
initialize RootSimplification as part of compilation. If you
look at 'compileDeclaredMap' you will see that is changes values
of some global variable. So now resonable guess is that error
is due to wrong setting of global variables, they are set for
compiling code, while to initialize RootSimplification we
need evaluation. It took me some time to find responsible
variable (it was '$insideCompileBodyIfTrue'). However, the
point is that error message + info from backtrace was sufficient
to get resonable idea about nature of the problem. I do not
think that different error message could do better. And
actually, main drawback of backtrace is that it is long.

Coming back to error messages, I think that fundamental
problem is that users have trouble relating low level
errors with high level actions. That is hard problem,
backtrace can help linking low level error to higher
level calls, but fundamentally problem is hard. We can
try to predict possible errors and add more checks, but
this requires more effort.

Concerning 'error' routine: automatically printing more
info could help sometimes. But most of the time extra
info will be irrelevant, so IMO if extra info is printed
it shoule be either under user control or by explict
request from programmer invoking 'error'.

--
Waldek Hebisch

Ralf Hemmecke

no leída,
30 mar 2024, 5:31:51 p.m.30 mar
para fricas...@googlegroups.com
On 3/30/24 00:43, Waldek Hebisch wrote:
> Compiler knows function name and constructor name. Note however
> that FriCAS types are parametrized, and type parameter are known
> only at runtime.

Waldek, that sounds as if printing function and constructor name would
be quite easy to achieve.

Yes, the parameters of the constructor would be nice, but for me it
would already be pretty helpful to know function and constructor name.

Ralf

Waldek Hebisch

no leída,
30 mar 2024, 9:46:50 p.m.30 mar
para fricas...@googlegroups.com
In a sense yes. There are limitations:
1) 'error' needs special treatment in the compiler because
'error' means abnormal exit from a function, so no need
for return value. Without that knowledge you would have
to write silly code like

my_error("error")
return some_dummy

to satisfy type checker. Theoretically 'Exit' as return type
could be used for this purpose, but I am affraid that it only
works in the interpeter.
2) Currently 'error' calls 'error' in 'g-error.boot'. So there
is one argument and to call _must_ go to 'errorSupervisor'
before it prints anything. Namely, 'errorSupervisor' may
trap errors, in which case nothing should be printed.
3) 'error' messages are most important in unexpected situations.
Which means that we want to keep error handlers as simple as
possible. Otherwise there is real risk that when "interesting"
error hapen we will get crash in error handler instead of
error message.

Currently actual code for 'error' is generated in 'compForm1'
in 'compiler.boot'. Handling is dead simple:

op="error" =>
#argl = 1 =>
arg := first(argl)
u := comp(arg, $String, e) =>
[[op, u.expr], m, e]
SAY ['"compiling call to error ", argl]
u := outputComp(arg, e) =>
[[op, ['LIST, ['QUOTE, 'mathprint], u.expr]], m, e]
nil
SAY ['"compiling call to error ", argl]
nil

So, if function name is 'error' and there is one argument it
tries to compile this aregument, and if succesful generates call
to 'error' at Boot level passing to computed value of the argument.
Otherwise, in case of one argument it tries to compile agument as
an output form, if that warks it callse Boot hadler giving it
wrapped OutputForm.

Of none of the above works call is treated as error is source
code. There is backtracking in Spad compiler, so theoretically
soemthing else could compile the call, but AFAICS all things
go trough 'compForm1', so probably different treatment is
not possible.

Now, what could we change easily? We could add two or three
argument error at Boot level and call it with extra data.
For example, passing '%' to handler would give it complete
information about current constructor ('%' contains domain
vector which contains all runtime information about type,
including constructor name and parameters). We could pass
'$op' which IIRC contains current function name.

Attached is a little patch which changes error function to
'error3' and adds two extra paramters, that is constructor name
and function name.

You need to add definition of 'error3', for example:

error3(con, fun, mess) ==
errorSupervisor($AlgebraError, [STRCONC(con, '"$", fun, '": "), mess])

Note: to test patch 'compiler.boot' and read it. Then read
boot file with definition of 'error3'.

--
Waldek Hebisch
compiler.diff

Ralf Hemmecke

no leída,
31 mar 2024, 4:46:37 p.m.31 mar
para fricas...@googlegroups.com
Hello Waldek,

> Attached is a little patch which changes error function to
> 'error3' and adds two extra paramters, that is constructor name
> and function name.
>
> You need to add definition of 'error3', for example:
>
> error3(con, fun, mess) ==
> errorSupervisor($AlgebraError, [STRCONC(con, '"$", fun, '": "), mess])
>
> Note: to test patch 'compiler.boot' and read it. Then read
> boot file with definition of 'error3'.

Thank you for that patch. That is really progress. And helps me a lot.
Looks good to me, at least.

I only think that it would be better to use

========
error3(con, fun, mess) ==
errorSupervisor($AlgebraError, [STRCONC(fun, '" $ ", con, '": "),
mess])
========

that is, spaces around $, and fun and con excanged.

I also saw that it might be possible that fun and/or con could be NIL. I
do not yet see where that could happen, but maybe for those cases the
code of error3 should be different. But, honestly, if STRCONC allows NIL
as argument, then the $ makes clear enough what is function name and
what constructor.

I'd be happy if this could make it into the next release.

Ralf

Waldek Hebisch

no leída,
31 mar 2024, 6:27:36 p.m.31 mar
para fricas...@googlegroups.com
On Sun, Mar 31, 2024 at 10:46:34PM +0200, Ralf Hemmecke wrote:
> Hello Waldek,
>
> > Attached is a little patch which changes error function to
> > 'error3' and adds two extra paramters, that is constructor name
> > and function name.
> >
> > You need to add definition of 'error3', for example:
> >
> > error3(con, fun, mess) ==
> > errorSupervisor($AlgebraError, [STRCONC(con, '"$", fun, '": "), mess])
> >
> > Note: to test patch 'compiler.boot' and read it. Then read
> > boot file with definition of 'error3'.
>
> Thank you for that patch. That is really progress. And helps me a lot.
> Looks good to me, at least.
>
> I only think that it would be better to use
>
> ========
> error3(con, fun, mess) ==
> errorSupervisor($AlgebraError, [STRCONC(fun, '" $ ", con, '": "), mess])
> ========
>
> that is, spaces around $, and fun and con excanged.

Yes, fun should go first. I do not understand why you want spaces
around '$'. Usual way it to write this without extra spaces,
also in hand written error messages.

>
> I also saw that it might be possible that fun and/or con could be NIL. I do
> not yet see where that could happen, but maybe for those cases the code of
> error3 should be different.

Well, the patch is just proof of concept. There are corner cases
which should be handled in reasonable way. Note that initialization of
constructors is outside functions, so there in no function name.
And initialization may signal errors. I am not sure if constructor
can be NIL, that should be investigated before commiting better
version. Also, for nested functions '$op' contains name of surrounding
function. In case of anonymous functions we have no name. That
should be handled in some way.

Note that currently there are two legal variants of error, the second
one allowing math formatting. The patch only handles first form, the
second one needs a bit more work.

--
Waldek Hebisch

Ralf Hemmecke

no leída,
1 abr 2024, 4:46:46 a.m.1 abr
para fricas...@googlegroups.com
On 4/1/24 00:27, Waldek Hebisch wrote:
>> I also saw that it might be possible that fun and/or con could be NIL. I do
>> not yet see where that could happen, but maybe for those cases the code of
>> error3 should be different.
>
> Well, the patch is just proof of concept. There are corner cases
> which should be handled in reasonable way. Note that initialization of
> constructors is outside functions, so there in no function name.
> And initialization may signal errors. I am not sure if constructor
> can be NIL, that should be investigated before commiting better
> version. Also, for nested functions '$op' contains name of surrounding
> function. In case of anonymous functions we have no name. That
> should be handled in some way.

Honestly, I think that cases where con or fun are NIL should not count
as trouble. Even if the patch shows correct fun$con in 80% of the cases
and has some cases where it shows NIL$con or fun$NIL, I would still see
it as progress.

> Note that currently there are two legal variants of error, the second
> one allowing math formatting. The patch only handles first form, the
> second one needs a bit more work.

What exactly do you mean by "math formatting"? The the "error" function
that we speak about allows only one argument which is of type String.
Your comment says that I do not use "error" to its full power.
Seemingly, I have not yet come across such "math formatting" option.
Can you give a pointer.

Ralf

Prof. Dr. Johannes Grabmeier

no leída,
2 abr 2024, 4:50:15 a.m.2 abr
para fricas...@googlegroups.com
in my recent installed system

                       FriCAS Computer Algebra System
                Version: FriCAS 1.3.10 built with sbcl 2.4.0
                   Timestamp: Mo 11 Mär 2024 17:56:31 CET
-----------------------------------------------------------------------------
   Issue )copyright to view copyright notices.
   Issue )summary for a summary of useful system commands.
   Issue )quit to leave FriCAS and return to shell.
--------------------------------------------------------------------------

the history feature is broken:

(3) -> x+y

   (3)  y + x
Type: Polynomial(Integer)
(4) -> )history )write xx

debugger invoked on a SIMPLE-CONDITION in thread
#<THREAD "main thread" RUNNING {7006620003}>:
  break

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [CONTINUE] Return from BREAK.
  1: [ABORT   ] Exit from the current thread.

(|writeInputLines| (|xx|) 1)
   source: (|histInputFileName| |fn|)
0]



--
Mit freundlichen Grüßen

Johannes Grabmeier

Prof. Dr. Johannes Grabmeier,
Köckstraße 1, D-94469 Deggendorf
Tel. +49-(0)-991-2979584, Tel. +49-(0)-151-681-70756
Fax: +49-(0)-991-2979592

Qian Yun

no leída,
2 abr 2024, 7:51:58 a.m.2 abr
para fricas...@googlegroups.com
It is caused by commit 68a3e8ee in 2023-Feb-9, the removal of
"makePathname" in "histInputFileName".

So the fix is the following. Please review it before I do the
commit.

- Qian

diff --git a/src/interp/i-syscmd.boot b/src/interp/i-syscmd.boot
index 8e337d59..37c0e6ea 100644
--- a/src/interp/i-syscmd.boot
+++ b/src/interp/i-syscmd.boot
@@ -1308,7 +1308,7 @@ histFileName() ==
histInputFileName(fn) ==
null fn =>
make_filename0($interpreterFrameName, 'INPUT)
- make_filename0(fn, 'INPUT)
+ make_filename0(PNAME fn, 'INPUT)


initHist() ==
@@ -1427,6 +1427,7 @@ writeInputLines(fn,initial) ==
-- in case we can't find a breaking point
if not done then n := 0
lineList := [vec,:lineList]
+ fn := first(fn)
file := histInputFileName(fn)
maybe_delete_file(file)
inp := MAKE_OUTSTREAM(file)

Grégory Vanuxem

no leída,
2 abr 2024, 9:51:58 a.m.2 abr
para fricas...@googlegroups.com
Hello,

Seems to work fine, before:

============================================
(3) -> )hist )show
[1]
1+7
[2]
fibonacci %
(3) -> )hist )write truc.input

debugger invoked on a SIMPLE-CONDITION in thread
#<THREAD tid=22 "main thread" RUNNING {1002708003}>:
break

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
0: [CONTINUE] Return from BREAK.
1: [ABORT ] Exit from the current thread.

(|writeInputLines| (|truc.input|) 1)
error finding frame source: Bogus form-number: the source file has probably
changed too much to cope with.
source: NIL
0] (quit)
============================================

After:

============================================
(1) -> fibonacci(1+7)

(1) 21
Type: PositiveInteger
(2) -> %*factorial(9)

(2) 7620480
Type: PositiveInteger
(3) -> )hist )write foo.input
Edit foo.input to see the saved input lines.
(3) -> )sys cat foo.input
fibonacci(1+7)
%*factorial(9)
)hist )write foo.input
(3) ->
========================================

Regards,

- Greg
> --
> You received this message because you are subscribed to the Google Groups "FriCAS - computer algebra system" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to fricas-devel...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/fricas-devel/d01bdbc8-c95e-44ec-9cb3-38f511d34e8d%40gmail.com.

Waldek Hebisch

no leída,
2 abr 2024, 2:08:59 p.m.2 abr
para fricas...@googlegroups.com
On Tue, Apr 02, 2024 at 07:51:53PM +0800, Qian Yun wrote:
> It is caused by commit 68a3e8ee in 2023-Feb-9, the removal of
> "makePathname" in "histInputFileName".
>
> So the fix is the following. Please review it before I do the
> commit.

AFAICS the PNAME part is not needed: make_filename0 converts
symbols to strings.

At first glance, it looks that change below would break
')history )save' and ')undo'. I think that we need to change
'historySpad2Cmd' to call an intermediate function to
convert arguments.
> --
> You received this message because you are subscribed to the Google Groups "FriCAS - computer algebra system" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to fricas-devel...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/fricas-devel/d01bdbc8-c95e-44ec-9cb3-38f511d34e8d%40gmail.com.

--
Waldek Hebisch

Qian Yun

no leída,
2 abr 2024, 8:36:42 p.m.2 abr
para fricas...@googlegroups.com


On 4/3/24 02:08, Waldek Hebisch wrote:
> On Tue, Apr 02, 2024 at 07:51:53PM +0800, Qian Yun wrote:
>> It is caused by commit 68a3e8ee in 2023-Feb-9, the removal of
>> "makePathname" in "histInputFileName".
>>
>> So the fix is the following. Please review it before I do the
>> commit.
>
> AFAICS the PNAME part is not needed: make_filename0 converts
> symbols to strings.
>
> At first glance, it looks that change below would break
> ')history )save' and ')undo'. I think that we need to change
> 'historySpad2Cmd' to call an intermediate function to
> convert arguments.

Yes, you are right about both points.

I believe the following is enough:

diff --git a/src/interp/i-syscmd.boot b/src/interp/i-syscmd.boot
index 8e337d59..31d2a1fe 100644
--- a/src/interp/i-syscmd.boot
+++ b/src/interp/i-syscmd.boot
@@ -1367,7 +1367,7 @@ historySpad2Cmd() ==
opt = 'show => showHistory optargs
opt = 'change => changeHistListLen first optargs
opt = 'restore => restoreHistory optargs
- opt = 'write => writeInputLines(optargs,1)
+ opt = 'write => writeInputLines(first optargs, 1)
'done



- Qian

Waldek Hebisch

no leída,
2 abr 2024, 9:52:46 p.m.2 abr
para fricas...@googlegroups.com
On Wed, Apr 03, 2024 at 08:36:37AM +0800, Qian Yun wrote:
>
>
> On 4/3/24 02:08, Waldek Hebisch wrote:
> > On Tue, Apr 02, 2024 at 07:51:53PM +0800, Qian Yun wrote:
> > > It is caused by commit 68a3e8ee in 2023-Feb-9, the removal of
> > > "makePathname" in "histInputFileName".
> > >
> > > So the fix is the following. Please review it before I do the
> > > commit.
> >
> > AFAICS the PNAME part is not needed: make_filename0 converts
> > symbols to strings.
> >
> > At first glance, it looks that change below would break
> > ')history )save' and ')undo'. I think that we need to change
> > 'historySpad2Cmd' to call an intermediate function to
> > convert arguments.
>
> Yes, you are right about both points.
>
> I believe the following is enough:

Yes, I think so. Please commit.

>
> diff --git a/src/interp/i-syscmd.boot b/src/interp/i-syscmd.boot
> index 8e337d59..31d2a1fe 100644
> --- a/src/interp/i-syscmd.boot
> +++ b/src/interp/i-syscmd.boot
> @@ -1367,7 +1367,7 @@ historySpad2Cmd() ==
> opt = 'show => showHistory optargs
> opt = 'change => changeHistListLen first optargs
> opt = 'restore => restoreHistory optargs
> - opt = 'write => writeInputLines(optargs,1)
> + opt = 'write => writeInputLines(first optargs, 1)
> 'done
>

--
Waldek Hebisch

Ralf Hemmecke

no leída,
3 abr 2024, 11:19:06 a.m.3 abr
para fricas...@googlegroups.com
Hi Waldek,

I've now tried to compile all of FriCAS with your patch (adding the
error3 function to g-error.boot).

https://github.com/fricas/fricas/compare/master...hemmecke:fricas:wip/error3.patch

Branch "wip/error3" at my github repo:

https://github.com/hemmecke/fricas/tree/wip/error3

It aborts the compilation with the log below. Obiously while compiling
(in parallel) the file xpfact.spad.

"master" compiled fine on that machine so the problem must come from
your patch, but I do not see why this would be related.

Any hints?

Ralf

====================================================================

compiling local lift1 : (FreeMonoid
vl,XDistributedPolynomial(vl,Polynomial F),Integer,FreeMonoid
vl,XDistributedPolynomial(vl,Polynomial
F),Integer,F,XDistributedPolynomial(vl,Polynomial F),Boolean) ->
Record(l_fac: XDistributedPolynomial(vl,Polynomial F),r_fac:
XDistributedPolynomial(vl,Polynomial F),residual:
XDistributedPolynomial(vl,Polynomial F),nsym: Union(Symbol,none))
Semantic Errors:
[1] algebraic_solution: sol1 is BOTH a variable and a literal

Warnings:
[1] top_split: k has no value
[2] lexquo: quotient has no value
[3] lexquo: remainder has no value
[4] left_ext_GCD: quotient has no value
[5] left_ext_GCD: remainder has no value
[6] XDP_to_YDP: k has no value
[7] XDP_to_YDP: c has no value
[8] eval_YDP: c has no value
[9] eval_YDP: k has no value
[10] eval_YDP: lt2 has no value
[11] rational_solution: sol has no value
[12] overlap_steps: res has no value
[13] lift1: rdc has no value
[14] lift1: ldc has no value
[15] lift1: lf1 has no value

****** comp fails at level 4 with expression: ******
error in function lift1

(SEQ (|:=| (|:| |nsu| (|Union| (|Symbol|) "none")) "none")
(|:=| |lcw| (|restn| |lw| (- |d1| |j|))) (|:=| |rop| (|lquo| |rfy|
|lcw|))
(IF (= |rop| 0)
(SEQ (|:=| |rf1p| (|lquo| |rp| |lw|))
(|:=| |rf1| (* (|::| (/ 1 |lc|) (|Polynomial| F)) |rf1p|))
(|:=| |rp| (- |rp| (* |lfy| |rf1|)))
(|:=| |lf1| (|rquo| |rp| |rw|))
(|exit| 1 (|:=| |rp| (- |rp| (* |lf1| |rfy|)))))
(SEQ (|:=| |rcw| (|firstn| |rw| |j|))
(|:=| |lop| (|rquo| |lfy| |rcw|))
(|:=| |row| (* |lw| (|maxdeg| |rop|)))
(|exit| 1
(IF (= |lop| 0)
(SEQ (|:=| |lf1| (|rquo| |rp| |rw|))
(|:=| |rp| (- |rp| (* |lf1| |rfy|)))
(|:=| |rf1p| (|lquo| |rp| |lw|))
(|:=| |rf1|
(* (|::| (/ 1 |lc|) (|Polynomial| F)) |rf1p|))
(|exit| 1 (|:=| |rp| (- |rp| (* |lfy| |rf1|)))))
(SEQ (|:=| |low| (* (|maxdeg| |lop|) |rw|))
(|exit| 1
(IF (< |row| |low|)
(SEQ (|:=| |lf1| (|rquo| |rp| |rw|))
(|:=| |rp| (- |rp| (* |lf1| |rfy|)))
(|:=| |rf1p| (|lquo| |rp| |lw|))
(|:=| |rf1|
(* (|::| (/ 1 |lc|) (|Polynomial| F))
|rf1p|))
(|exit| 1
(|:=| |rp| (- |rp| (* |lfy| |rf1|)))))
(IF (< |low| |row|)
(SEQ (|:=| |rf1p| (|lquo| |rp| |lw|))
(|:=| |rf1|
(* (|::| (/ 1 |lc|)
(|Polynomial| F))
|rf1p|))
(|:=| |rp| (- |rp| (* |lfy| |rf1|)))
(|:=| |lf1| (|rquo| |rp| |rw|))
(|exit| 1
(|:=| |rp| (- |rp| (* |lf1|
|rfy|)))))
(IF |o_case|
(SEQ
(|:=| |ns| ((|Sel| (|Symbol|)
|new|)))
(|:=| |nsu| |ns|)
(|:=| |nc|
((|Sel| (|Polynomial| F)
|monomial|) 1
|ns| 1))
(|:=| |oc| (|coefficient| |rp|
|low|))
(|:=| |rf1p| (|lquo| |rp| |lw|))
(|:=| |rf1|
(* (|::| (/ 1 |lc|)
(|Polynomial| F))
|rf1p|))
(|:=| |lf1| (|rquo| |rp| |rw|))
(|:=| |rf1| (+ |rf1| (* |nc| |rop|)))
(|:=| |lf1|
(- |lf1|
(*
(+
(|::| (/ |oc| |lc|)
(|Polynomial| F))
|nc|)
|lop|)))
(|exit| 1
(|:=| |rp|
(- (- |rp| (* |lfy| |rf1|))
(* |lf1| |rfy|)))))
(SEQ
(|:=| |oc| (|coefficient| |rp|
|low|))
(|:=| |dif_p|
(- (* |lfy| |rop|) (* |lop| |rfy|)))
(|exit| 1
(IF (= |dif_p| 0)
(|error| "impossible 1")
(SEQ (|:=| |dw| (|maxdeg|
|dif_p|))
(|exit| 1
(IF (>= |dw| |low|)
(|error|
"impossible 2")
(SEQ
(|:=| |dc|
(|coefficient| |rp|
|dw|))
(|:=| (|:| |rdc|
F) 0)
(|:=| (|:| |ldc|
F) 0)
(|:=|
(|:| |ldc0|

(|Polynomial| F))
(SEQ
(|:=| |rqu|
(|lquo| |dw|
|lw|))
(|exit| 1
(IF (|case| |rqu|
"failed")
0
(SEQ
(|:=| |rdc|
(|ground|

(|coefficient|
|rop|
(@ |rqu|

(|FreeMonoid|

|vl|)))))
(|exit| 1
(* (/ 1
|lc|)

|dc|)))))))
(|:=|
(|:| |rdc0|

(|Polynomial| F))
(SEQ
(|:=| |lqu|
(|rquo| |dw|
|rw|))
(|exit| 1
(IF (|case| |lqu|
"failed")
0
(SEQ
(|:=| |ldc|
(|ground|

(|coefficient|
|lop|
(@ |lqu|

(|FreeMonoid|

|vl|)))))
(|exit| 1
|dc|))))))
(|:=| |piv2| (-
|rdc| 1))
(|exit| 1
(IF (= |piv2| 0)
(|error|
"impossible 3")
(SEQ
(|:=| |nc2|
(* (/ 1
|piv2|)
(+
(-
(- |dc|

|ldc0|)
|rdc0|)
(* |ldc|

|oc|))))
(|:=| |nc1|
(- (- |oc|)
|nc2|))
(|:=| |rf1p|
(|lquo| |rp|
|lw|))
(|:=| |rf1|
(*
(|::| (/
1 |lc|)

(|Polynomial|
F))
|rf1p|))
(|:=| |rf1|
(+ |rf1|
(* |nc1|
|rop|)))
(|:=| |lf1|
(|rquo| |rp|
|rw|))
(|:=| |lf1|
(+ |lf1|
(* |nc2|
|lop|)))
(|exit| 1
(|:=| |rp|
(-
(- |rp|
(* |lfy|

|rf1|))
(* |lf1|

|rfy|)))))))))))))))))))))))
(|exit| 1 (|construct| | << lf1 >> | |rf1| |rp| |nsu|)))
****** level 4 ******
$x:= lf1
$m:= $EmptyMode
$f:=
((((|nsu| #) (|rdc0| #) (|ldc| #) (|ldc0| #) ...)
((|rop| #) (|lcw| #) (|nsu| # #) (|o_case| # #) ...)
((|overlap_steps| #) (|#| #) (< #) (<= #) ...)
((|my_mul| #) (|get_algebraic_solution| #)) ...))

>> Apparent user error:
NoValueMode
is an unknown mode

(1) -> cp XPFACT.NRLIB/XPFACT.fasl
/dev/shm/hemmecke/fricas/b/target/x86_64-linux-gnu/algebra/XPFACT.fasl.tmp
cp: cannot stat 'XPFACT.NRLIB/XPFACT.fasl': No such file or directory
make[4]: *** [spad.mak:12205:
/dev/shm/hemmecke/fricas/b/target/x86_64-linux-gnu/algebra/XPFACT.fasl]
Error 1
make[4]: Leaving directory '/dev/shm/hemmecke/fricas/b/src/algebra'
make[3]: *** [Makefile:714: do-update-spads] Error 2
make[3]: Leaving directory '/dev/shm/hemmecke/fricas/b/src/algebra'
make[2]: *** [Makefile:586: all-ax] Error 2
make[2]: Leaving directory '/dev/shm/hemmecke/fricas/b/src/algebra'
make[1]: *** [Makefile:243: all-algebra] Error 2
make[1]: Leaving directory '/dev/shm/hemmecke/fricas/b/src'
make: *** [Makefile:250: all-src] Error 2

real 2m4,195s
user 14m47,877s
sys 1m18,482s

Waldek Hebisch

no leída,
3 abr 2024, 12:41:54 p.m.3 abr
para fricas...@googlegroups.com
On Wed, Apr 03, 2024 at 05:19:03PM +0200, Ralf Hemmecke wrote:
> Hi Waldek,
>
> I've now tried to compile all of FriCAS with your patch (adding the error3
> function to g-error.boot).
>
> https://github.com/fricas/fricas/compare/master...hemmecke:fricas:wip/error3.patch
>
> Branch "wip/error3" at my github repo:
>
> https://github.com/hemmecke/fricas/tree/wip/error3
>
> It aborts the compilation with the log below. Obiously while compiling (in
> parallel) the file xpfact.spad.
>
> "master" compiled fine on that machine so the problem must come from your
> patch, but I do not see why this would be related.
>
> Any hints?

Well, AFAICS this is one of limitations of current compiler: 'error'
gets special treatment, but only when it is translated to Boot
function called 'error'. If you rename 'error3' to 'error', then
the file will compile. But I expect that such rename will cause
trouble, so I do not think it is a practical solution.

BTW: my guess is that trouble is due to following pattern:

piv2 = 0 => error "impossible 3"
...
lf1 := rquo(rp, rw)
lf1 := lf1 + nc2*lop

Thanks to special treatment of 'error' compiler knows that
lf1 is well defined at the end of this sequence. But
without special treatment compiler thinks that 'lf1' may
be undefined when the sequence is finished.

One could work around this by giving lf1 and rf1 explicit
type declarations at start of 'lift1', like:

lf1 : YDP
rf1 : YDP

but this is somewhat suboptimal, as it needs more code and
weakens compiler checking.
> --
> You received this message because you are subscribed to the Google Groups "FriCAS - computer algebra system" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to fricas-devel...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/fricas-devel/b3ded5b9-391d-428f-b66f-65effde04b16%40hemmecke.org.

--
Waldek Hebisch

Waldek Hebisch

no leída,
3 abr 2024, 1:00:35 p.m.3 abr
para fricas...@googlegroups.com
On Wed, Apr 03, 2024 at 05:19:03PM +0200, Ralf Hemmecke wrote:
> Hi Waldek,
>
> I've now tried to compile all of FriCAS with your patch (adding the error3
> function to g-error.boot).
>
> https://github.com/fricas/fricas/compare/master...hemmecke:fricas:wip/error3.patch
>
> Branch "wip/error3" at my github repo:
>
> https://github.com/hemmecke/fricas/tree/wip/error3
>
> It aborts the compilation with the log below. Obiously while compiling (in
> parallel) the file xpfact.spad.
>
> "master" compiled fine on that machine so the problem must come from your
> patch, but I do not see why this would be related.

Attached diff adds special handling for 'error3'. I principle
we should have special type (or something internal to the compiler)
to mark code which does not return. But in the patch I just add
extra line making 'error3' magic (like 'error').

--
Waldek Hebisch
compiler.diff

Ralf Hemmecke

no leída,
3 abr 2024, 1:09:45 p.m.3 abr
para fricas...@googlegroups.com
On 4/3/24 18:41, Waldek Hebisch wrote:
> Well, AFAICS this is one of limitations of current compiler: 'error'
> gets special treatment, but only when it is translated to Boot
> function called 'error'. If you rename 'error3' to 'error', then
> the file will compile. But I expect that such rename will cause
> trouble, so I do not think it is a practical solution.

That actually brings me to the question whether overloading in BOOT is
also supposed to work, i.e., whether I can have

error(x) == errorSupervisor($AlgebraError,x)

error(con, fun, mess) ==
errorSupervisor($AlgebraError, [STRCONC(fun, '" $ ", con, '": "),
mess])

at the same time. I guess no.

> BTW: my guess is that trouble is due to following pattern:
>
> piv2 = 0 => error "impossible 3"
> ...
> lf1 := rquo(rp, rw)
> lf1 := lf1 + nc2*lop
>
> Thanks to special treatment of 'error' compiler knows that
> lf1 is well defined at the end of this sequence. But
> without special treatment compiler thinks that 'lf1' may
> be undefined when the sequence is finished.
>
> One could work around this by giving lf1 and rf1 explicit
> type declarations at start of 'lift1', like:
>
> lf1 : YDP
> rf1 : YDP
>
> but this is somewhat suboptimal, as it needs more code and
> weakens compiler checking.

OK, that would have been something that I would have tried to do, but I
could not see how this would be related to the error3 function.
Even now I do not quite see it. Looks like type checking is done after
compForm1 was executed so that the typechecker sees error3 and does not
know that this, in fact, includes a RETURN-FROM-FUNCTION.

OK, that are compiler internals that I am not so much interested in.
However, your statement about the declarations bothered me a bit.
First of all, I do not think that declaring the types of variables is a
bad idea, since it is an easy hint for the programmer to understand the
code. So that point of your "suboptimal" does not count for me.
However, you say something about "weakens compiler checking", and that I
don't understand at all. Up to know I would have guessed that when I
declare the type of a variable, the compiler also checks that in places
where this variable is used (or assigned), the actual types match with
what I have declared. Is this not the case?

Ralf

Waldek Hebisch

no leída,
3 abr 2024, 1:48:44 p.m.3 abr
para fricas...@googlegroups.com
On Wed, Apr 03, 2024 at 07:09:41PM +0200, Ralf Hemmecke wrote:
> On 4/3/24 18:41, Waldek Hebisch wrote:
> > Well, AFAICS this is one of limitations of current compiler: 'error'
> > gets special treatment, but only when it is translated to Boot
> > function called 'error'. If you rename 'error3' to 'error', then
> > the file will compile. But I expect that such rename will cause
> > trouble, so I do not think it is a practical solution.
>
> That actually brings me to the question whether overloading in BOOT is also
> supposed to work, i.e., whether I can have
>
> error(x) == errorSupervisor($AlgebraError,x)
>
> error(con, fun, mess) ==
> errorSupervisor($AlgebraError, [STRCONC(fun, '" $ ", con, '": "), mess])
>
> at the same time. I guess no.

There is no overloading in Boot.

> However, your statement about the declarations bothered me a bit.
> First of all, I do not think that declaring the types of variables is a bad
> idea, since it is an easy hint for the programmer to understand the code. So
> that point of your "suboptimal" does not count for me.
> However, you say something about "weakens compiler checking", and that I
> don't understand at all. Up to know I would have guessed that when I declare
> the type of a variable, the compiler also checks that in places where this
> variable is used (or assigned), the actual types match with what I have
> declared. Is this not the case?

Yes. However, here there is question of tracking values. If you
give types you should do

x : T := v

and not

x : T
...
x := v

The point is that type should be assigned to variable together with
value. That way uninitialized variable leads to type error.
Declaring type in advance (before assignment) effectively disables
detection of uninitialized variables. Sometimes Spad can not
see that variable is initialized with correct type, then we have
to give declaration in advance. But if possible such advance
declarations should be avoided.

--
Waldek Hebisch

Ralf Hemmecke

no leída,
3 abr 2024, 2:02:05 p.m.3 abr
para fricas...@googlegroups.com
On 4/3/24 19:48, Waldek Hebisch wrote:
> Yes. However, here there is question of tracking values. If you
> give types you should do
>
> x : T := v
>
> and not
>
> x : T
> ...
> x := v

OK. I think you mentioned some time ago that in SPAD writing x:T
basically means "assigning a variable x with and uninitialized value".
(Strange concept, but AFAIU, there are no declarations in SPAD.)
I would anyway always write x:T:=v.

Thank you for the explanation.

Ralf

Responder a todos
Responder al autor
Reenviar
0 mensajes nuevos