Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
tef
May 30, 2004

-> some l-system crap ->

dwazegek posted:

I'm partial to the almost always applicable "result" :downs:

See, where you might use "result" I would use bln_flg_tst_cnd_args_x.

Adbot
ADBOT LOVES YOU

tef
May 30, 2004

-> some l-system crap ->

nebby posted:

For example, if you are writing a method called countOfApplesInBasket() that returns a count of apples, if I see the line "result += 1;" I have to look at context to determine wtf result is.

The best bit is I don't even have to think up new jokes, you're still saying the same things.

Mainly because a lot of people will waste a lot of time arguing with you, here is what I see as the condensed nebby experience:

Fake Nebby posted:

Naming schemes are hard to get right. Thus we should use a series of cryptonyms to identify each indivudal type. The best thing to do is mmenonics for each data structure used.

For example, Say I wanted to store a list of student scores

– Bad Idea studentScores = { 'james': 80 , ... }

See, I don't know the type of information that studentScores is - names of variables should reflect the implementation rather than the intent. You don't seem to understand that "Human Readable Names are Evil".

Now, what we are actually storing is a hash which uses student names as keys (strings) pointing to percentages (ints). This leads to the obvious naming scheme

scr_pcn_int = sn_str_hash_scr_pcn_int[sn_str]

Now, when I look a this I can see that we are retrieving a percentage score in an int from a hash using a string containing a student name.

The other reason this is a fantastic idea is that context is really hard, I mean, when I read a sentence and the word "james" appears, I don't understand what it is refering to, unless I prefix it with the relevant information.

Really, when you're looking at code — you do so at one lexical token at a time — this is why we have to ensure that we have all the information to hand.

Now, let's take a function written by some amatuer programmer who has yet to reach my level of enlightenment:

code:
class AppleBasket
   count = 0
   def addApple(s)
       s.count++
   def takeApple(s)
       s.count--
   def numApples(s)
       return s.count
If I were to ignore the surrounding context of the program and focus on one part alone, say return s.count I have no idea what it means. Anyone who will edit this program will only see this line and they will be confused.

Redundant information is the key. Succinct code is useless. To demonstrate this I have improved the above program

code:
class AppleBasket
    int_app_cnt_tot = 0
    def addApple(applebasketself)
        applebasketself.int_app_cnt_tot++
    def takeApple(applebasketself)
        applebasketself.int_app_cnt_tot--
    def numApple(applebasketself)
        return applebasketself.int_app_cnt_tot
Although this looks like apps hungarian, and we are encoding the types of variables into the names, you are wrong and it is Systems, because I only do the good hungarian notation.

Now, when I see the line return applebasketself.int_app_cnt_tot I know exactly what it returns. I can finally trim down the excess space on my screen and get down to editing code with only one line displayed at a time.

I am hoping to apply this same system to make my forum posts more readable. You see, even comments and text can be analysed in the same way - one logical token at a time.

I could write something like /* calculates the size of the basket */, but that isn't obvious enough.

Remember "Human Readable Names are Evil" — what type is basket, what type is size, how it is calculated?. I think the new comment should read something like /* arith_calc:: int_size(apple_basket) */

This sort of redundancy defeats the enemy of the working programmer — context!. We need to keep at it. When I see a function like add(...) I have no idea how many arguments it takes. I am in the process of renaming all of my functions to have the arity appended to the end, so add(x,y) becomes add_takes_two_args(x,y). I would use add2(x,y), but you wouldn't know if it was the second adding function from the name alone.

Hopefully my methods will become widespread, and we can put an end to all of this uncessecary confusion.

On a more serious note — I did give up trying to debate the merits of nebby's ideas given his inability to argue them consistently (Apps vs System being the most obvious example).

(Edit: Another is that although you realise that inconsitent naming schemes are bad, you are yet to realise that a consistent naming scheme can be bad in a completely different way. You point out the trivial flaws of others (NumChild/NumChildren), hammer home ambiguitiy I've rarely seen and focus on statements at a macro level. You then take these as support for your scheme, rather than being innacurate criticisms of straw men)



Really his system of naming speaks more about his command of the english language (and his comfort in using it) than it does about his ability to program. It boils down to "Hungarian Notation will free you from the Tyranny of understaning things in context".


nebby posted:

You're forgetting that I explicitly said in all my posts I intentionally post on subjects that are controversial in order to spice things up.

A troll by any other name would smell as foul.

tef fucked around with this message at 06:05 on Mar 30, 2008

tef
May 30, 2004

-> some l-system crap ->
Dear nebby, victor, zbo:

drat kids get out my thread :argh:

If you really wish to beat this dead horse go and start a new thread so we can go back to making fun of crap code.

tef
May 30, 2004

-> some l-system crap ->
If we're going into unicode territory how about something like ∀ x ∈ l : print x; perhaps?

tef
May 30, 2004

-> some l-system crap ->

rotor posted:

We're gonna need bigger keyboards.

This do?

tef
May 30, 2004

-> some l-system crap ->

nebby posted:

Fortress doesn't count because you have to run the whole thing through LaTeX, and it's read only.

I believe you are looking for APL.

It needed special keyboard and editors:


Also:

Dijkstra posted:

APL is a mistake, carried through to perfection. It is the language of the future for the programming techniques of the past: it creates a new generation of coding bums.

tef
May 30, 2004

-> some l-system crap ->

nebby posted:

it doesn't appear APL is considered a universally discarded idea.

People liked the point free style and the array operators, but the heiroglyphs haven't been as popular.

nebby posted:

You could project APL in plain text

Infact, K and J are APL variants that use ascii only.

And going back a little to the glyphs, space cadet keyboard anyone ? (If you have ever wondered why the keybindings for emacs are a little mental, now you know)




nebby posted:

A bigger problem though is that Fortress doesn't let you mix domain languages (it's domain is higher mathematics, really) but that's an altogether different problem than the one APL and Fortress are trying to solve with symbology.

I think you're looking for katahdin.

code:
import "fortran.kat";
import "python.kat";

fortran {
  SUBROUTINE RANDOM(SEED, RANDX)
  ...
  END
}
python {
  seed = 128
  randx = 0
  for n in range(5):
    RANDOM(seed, randx)
    print randx
}

tef
May 30, 2004

-> some l-system crap ->

nebby posted:

Ha ha. It's obviously even more advanced than Hungarian, it's the elusive md5(rand()) notation.

I like this scheme, it has the following advantages:

Unique names without collisions, and it sorts the naming problem once and for all. By avoiding programmer input you can avoid a lot of arguments and debate.

And of course with editor support you could link these 64 bit numbers to unicode characters to make them stand out visually.

Although you aren't encoding the type information - you avoid an english language bias. This means that it is an even playing field for people in multi-lingual environments.

You could probably have a large lookup table for each one per project, and once you start using these 64-bit numbers it will come naturally.

tef
May 30, 2004

-> some l-system crap ->
I've gone about this at length on irc and will do so when provoked, but pretty much this is some of the ugliest code I've ever had to work on. Anti Pattern doesn't even begin to describe some of it.

Redundancy is good. This is why we have two different naming schemes within the code base, often small little details like numAdult vs NumAdults or numChildren vs NumChild, or QueryReturnDate vs DateBack. We also have at least four different functions that perform uppercase, including uc, uppercase and getuppercase.

There are three components to the project, two are kept in svn with manual version numbers in the top of every file, and the other is kept in the database. This would mean deploying is a nightmare, but it is ok we edit the database bits live and only push the svn code to production.

XSL turned out to be a bad choice of language for text mangling so it is augmented with vbscript heavily. Which has lead to some weird calling conventions - at least one function takes three arguments as a space seperated string like getfoo("3 2 1").

Nearly every function that is in use follows the abstraction inversion principal, it is better to pass one parameter in and have 140 cases inside, rather than pass two parameters in.

I can go on - it's only recently we have moved away from the 'stick everything in one file' development model. Although we still have a 'stick things with a similar name together, rather than things that call each other in the same directory' policy. It would be like doing an OO project where there is one file for each method name, and inside are the defintions for every type of object.

tef
May 30, 2004

-> some l-system crap ->

JoeNotCharles posted:

That's actually pretty close to a legitimate pattern.

I'll admit it can make sense, like putting all your include files in one directory, and all your shared objects in another when distributing them. I

I had a hard time thinking of an appropriate metaphor - and I meant putting every length method in length.c and every hashcode method in hashcode.c so the definition of each object would be spread around 15 or so files throughout the project.

In this specific instance, it only serves to ofuscate the structure - for some reason normal websites within the project are in per website directories, but more general templates are in part1/website1.xsl, part2/website1.xsl and so on. We *never* need to refer to things by the part that they are in, and always are doing per website things. (So, on top of the multiple naming schemes we have multiple directory structures too).

Oh and I just found out that in one part we have AirlineCode and in another we have AIrlineCode for the same variable.

tef
May 30, 2004

-> some l-system crap ->

Lexical Unit posted:

Old code expects longititude to be populated, new code expects longitude to be populated. Good night, and good luck.

The output of the screen scraper produces xml in <quote>...</quote> or sometimes <Quote>...</Quote>. Parts of the website expect <Quote>...</Quote> and so a series of search and replace operations have been tacked on to the website code to fix this. Even though we could fix it in the program itself now we are in the position of not being able to change the output format for fear of breaking other code.

I also managed to fix a number of bugs by sorting the output.

tef
May 30, 2004

-> some l-system crap ->
Have you read what you have written?

You're aguing against long functions in one paragraph and then arguing against terse code in the other.

Proper use of whitespace makes code easier to read, adding one brace to space code out is not a significant cognitive overhead.

tef fucked around with this message at 14:16 on May 8, 2008

tef
May 30, 2004

-> some l-system crap ->
Here is a bit of a security coding horror:

http://lists.debian.org/debian-security-announce/2008/msg00152.html

quote:

Luciano Bello discovered that the random number generator in Debian's
openssl package is predictable. This is caused by an incorrect
Debian-specific change to the openssl package (CVE-2008-0166). As a
result, cryptographic key material may be guessable.

This is a Debian-specific vulnerability which does not affect other
operating systems which are not based on Debian. However, other systems
can be indirectly affected if weak keys are imported into them.

It is strongly recommended that all cryptographic key material which has
been generated by OpenSSL versions starting with 0.9.8c-1 on Debian
systems is recreated from scratch. Furthermore, all DSA keys ever used
on affected Debian systems for signing or authentication purposes should
be considered compromised; the Digital Signature Algorithm relies on a
secret random value used during signature generation.

The first vulnerable version, 0.9.8c-1, was uploaded to the unstable
distribution on 2006-09-17, and has since propagated to the testing and
current stable (etch) distributions. The old stable distribution
(sarge) is not affected.

Affected keys include SSH keys, OpenVPN keys, DNSSEC keys, and key
material for use in X.509 certificates and session keys used in SSL/TLS
connections. Keys generated with GnuPG or GNUTLS are not affected,
though.

Here is the fix: http://svn.debian.org/wsvn/pkg-openssl/openssl/trunk/crypto/rand/md_rand.c?op=diff&rev=300&sc=1

(Yes, it is just adding in a line that was commented out.)

And why did this happen? http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=363516

They wanted to get rid of warning messages caused by valgrind.

At this point I think this says it best:

Linus Torvalds posted:

Please, we do NOT fix compiler warnings without understanding the code! That's a sure way to just introduce _new_ bugs, rather than fix old ones. So please, please, please, realize that the compiler is _stupid_, and fixing warnings without understanding the code is bad.

tef
May 30, 2004

-> some l-system crap ->

Smackbilly posted:

Maybe I'm just not understanding the code.

TSDK posted:

Not sure if I'm reading the thread right, but are they really relying on uninitialised variables as a source of random data?

The comment is wrong, and the warnings from purify *not valgrind - my bad* are spurious.

You can see that m is initialised by EVP_MD_CTX_init(&m); a few lines up, and buf is a parameter.

tef
May 30, 2004

-> some l-system crap ->

tef posted:

The comment is wrong, and the warnings from purify *not valgrind - my bad* are spurious.

You can see that m is initialised by EVP_MD_CTX_init(&m); a few lines up, and buf is a parameter.

It turns out I'm talking poo poo!

http://www.links.org/?p=327

Ben Laurie posted:

Usually it is bad to have any kind of dependency on uninitialised memory, but OpenSSL happens to include a rare case when its OK, or even a good idea: its randomness pool. Adding uninitialised memory to it can do no harm and might do some good, which is why we do it. It does cause irritating errors from some kinds of debugging tools, though, including valgrind and Purify. For that reason, we do have a flag (PURIFY) that removes the offending code. However, the Debian maintainers, instead of tracking down the source of the uninitialised memory instead chose to remove any possibility of adding memory to the pool at all. Clearly they had not understood the bug before fixing it.

So they fixed the code that added unitialised memory, by removing all calls that added things to the entropy pool.

tef fucked around with this message at 18:54 on May 13, 2008

tef
May 30, 2004

-> some l-system crap ->

TSDK posted:

3) Making a change to some code you don't fully understand without getting in touch with either the original author, or someone who could explain why it's doing what it is.

http://marc.info/?l=openssl-dev&m=114651085826293&w=2

An open ssl dev wrote in reply posted:

Kurt Roeckx schrieb:
> What I currently see as best option is to actually comment out
> those 2 lines of code. But I have no idea what effect this
> really has on the RNG. The only effect I see is that the pool
> might receive less entropy. But on the other hand, I'm not even
> sure how much entropy some unitialised data has.

Not much. If it helps with debugging, I'm in favor of removing them.
(However the last time I checked, valgrind reported thousands of bogus
error messages. Has that situation gotten better?)

tef
May 30, 2004

-> some l-system crap ->
Today we made the switch from:

Manually incrementing version numbers in the file, and putting them in the commit log, and manually cleaning up the mess when the version numbers caused svn conflicts.

To:

Committing, and letting svn handle the version stamp in the file.

:toot:

I did a lap of victory around the office when it happened, I've been begging to do this since day one, over three months ago.

tef fucked around with this message at 00:31 on May 16, 2008

tef
May 30, 2004

-> some l-system crap ->

tripwire posted:

Gotos have no place in OO (or really any kind of structured) programming. Maybe you'd feel more at home with fortran?

There is the interesting paper "Structured programming with Gotos" by donald knuth.

http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf

The horror of goto is using it in place of while, for and other looping and structured constructs. However there are occasions where a direct jump is needed and cannot be elegantly done with the existing constructs.

Even so knuth does suggest that goto not be used in high level languages.


Edit:

Perl had the nice thing of goto &function which was occasionally useful, and also allowed you to label loops so you could do break LOOP_NAME

tef
May 30, 2004

-> some l-system crap ->

PrBacterio posted:

I'm also one of those people who'd prefer the Pascal-style syntax of = as the comparison operator with := being used for assignments, instead of the C-style == for a comparison operator...)

= is for unification :v:

(Which is a mixture of non-destructive asignment and equality, X=3 succeeds if X is unbound (so, x is set to 3) or X is already set to 3. )

tef
May 30, 2004

-> some l-system crap ->

Zombywuf posted:

I can't help but feel you've missed everything that's wrong with the code I posted.

You didn't post it all either, the Boolean Utilities class has four methods. Only one of which uses the Formatter method, the other two use the ternary operator.

A method so useful he couldn't be bothered to use it.

tef
May 30, 2004

-> some l-system crap ->
Re Monkeypatching:

That's nice dearie, can we take this argument and beat it to death in a new thread please? :shobon:

tef
May 30, 2004

-> some l-system crap ->

Zombywuf posted:

Sometimes you don't or can't care if an operation fails.

code:
try:
  log_error(error)
except:
  pass

If you do this in our codebase I will nail your hands to the toilet.

If you don't care if it fails, you should be explicit in the failures to ignore.

code:
except IOError:
    pass
Isn't as bad and is a little more obvious what you're trying to do.


And signals are part of posix, not C :3: last time I checked.

tef
May 30, 2004

-> some l-system crap ->
So the functions are guaranteed just not their implmentation :c00l:

tef
May 30, 2004

-> some l-system crap ->
Hello, this is a message from the Zombywuf posting advisory service.

In my time of knowing Zombywuf I have made a number of observations on his behaviour and beliefs, and I think I can help somewhat here:

Here is a summary of what Zombywuf has to say:

quote:

I don't like python.

Here is a summary of the reasons for the above statement:

quote:

I do not like it because it does things differently from what I am used to. This comes down to the simple fact that python is not c++ or c, although sometimes the fact that python is not perl annoys me too.

There might be some technical details involved in the above reasons too, but I have omitted them for clarity.

There you have it. Now if all parties concerned wish to continue on this fruitless debate, you can all go and poo poo in a new thread in yospos.

tef
May 30, 2004

-> some l-system crap ->
I found out this week why certain bits of code are slow at work.


We have a cache of ticket prices - I thought this was a simple as the ticket details (people, date) being the key, and the price being the value in a hash.

It turns out that he constructs the key from the ticket details and the price, just to be sure.

Unfortunately this means he can't then do a simple lookup, so he iterates through the hash values to find it.


"iterating over the keys of a hash is like clubbing someone to death with a loaded Uzi." - larry wall.

tef
May 30, 2004

-> some l-system crap ->

Painless posted:

You might mean it could do. It doesn't actually do poo poo.

What if b[] is being modified in a different thread?

tef
May 30, 2004

-> some l-system crap ->

Zombywuf posted:

If you're playing guess-what-the-compiler-will-do you're wasting time.

Optimizing SQL is fun, eh ?

Context: This is the code zombywuf normally optimizes for performance, and most of that is nearly all guessing what the compiler will do (in a non-deterministic way)

tef fucked around with this message at 16:06 on Dec 24, 2008

tef
May 30, 2004

-> some l-system crap ->
Well, it does depend on the language. Being explicit in a dynamic language can help somewhat.

tef
May 30, 2004

-> some l-system crap ->
We need to do a number of database lookups on every page, but since 'this would be slow', we have a much better way of speeding things up.

Every 2 hours a lookup xml file is created, and pushed out to the production webservers. This is then loaded in, and all queries are performed locally as xpaths against it.

We have a few problems with this approach - it's hard to add information quickly to this process, and when it falls over it takes down the entire website. The last time was because the machine run out of disk space, and so a corrupted file was pushed out.


Some people think it might be easier to run queries against the database, and then cache the results locally. The lead architect vehemently disagrees, because looking things up in the database might incurr a "large DB performance hit".

tef
May 30, 2004

-> some l-system crap ->
The performance problems are all in the lead architects head , among many other problems.

He is the person who uses a hash like this (psedudocode):

code:
def set(hash, key, value):
    id = str(key) + str(value)
    hash[id] = value


def get(hash, key):
    for hkey,hvalue in hash.items():
        if hkey.startswith(key):
            return hvalue
I wish I was making this up.

Erk: I've already whinged about this:
http://forums.somethingawful.com/showthread.php?threadid=2803713&userid=0&perpage=40&pagenumber=30#post352266512

tef fucked around with this message at 15:36 on Jan 5, 2009

tef
May 30, 2004

-> some l-system crap ->

ShoulderDaemon posted:

There are real-world applications for which MD5 is currently completely compromised by the present attacks (third-party signatures being an incredibly relevant example, see recent X.509 CA shenanigans).



Everyone should have stopped using md5 about 4 years ago.

tef
May 30, 2004

-> some l-system crap ->
Did I mention pyodbc yet? Because I'm pretty sure it's installed on the machine you're using, and works with mssql

And there's an example somewhere in my old svn folder.

tef
May 30, 2004

-> some l-system crap ->

rhag posted:

As usual, the answer to that is: depends on your project.

I.e. if it's vapourware then running on perl6 is a good idea.

tef
May 30, 2004

-> some l-system crap ->
Then you should use haskell

tef
May 30, 2004

-> some l-system crap ->

Inverse Icarus posted:

code:
// checking below me
// no children to right or left
// i am a leaf node

this for new cobol title

tef
May 30, 2004

-> some l-system crap ->

Bhaal posted:

The ones in bold make the changes to 'this' and return a reference to itself. The ones without bold return a new object (by value) with the old one unchanged.

This has been coming up recently in the python thread. Nice to see it catching someone out

tef
May 30, 2004

-> some l-system crap ->
PHP is, though.

tef
May 30, 2004

-> some l-system crap ->
sort {$a+=$b} @list;

tef
May 30, 2004

-> some l-system crap ->
That is wrong.

I did sort {$a+=$b} @list;, you did my @sorted_list = sort { my $x = $a += $b; print "$x\n"; $x; } @list;.

Let's try this again.

code:
$ cat getupgetonup.pl 
#!perl
use Data::Dumper;
my @list = qw! -1 0 1 2 3 4 5 !;
sort { my $x = $a += $b; print "$x\n"; $x; } @list;
print Dumper \@list;


$ perl getupgetonup.pl 
$VAR1 = [
          '-1',
          '0',
          '1',
          '2',
          '3',
          '4',
          '5'
        ];

Adbot
ADBOT LOVES YOU

tef
May 30, 2004

-> some l-system crap ->
hello world in prolog :v:

code:
#!/usr/bin/env swipl -q -t start -f 

%% chmod +x pharmacon.prolog && ./pharmacon.prolog 

%% hello world program in stack form

helloworld([
    pushz,inc,inc,dup,dup,mul,mul,dup,dup,inc,mul,
    prc,pushz,inc,inc,inc,dup,dup,mul,mul,add,inc,
    inc,prc,add,dec,prc,prc,inc,inc,inc,prc,pushz,
    inc,inc,dup,dup,mul,dup,inc,mul,inc,mul,inc,inc,
    prc,pushz,inc,inc,inc,dup,inc,mul,swap,sub,prc,
    swap,dup,pushz,inc,inc,dup,dup,mul,mul,add,prc,
    swap,pushz,inc,inc,inc,add,dup,dec,dec,dec,prc,
    pop,prc,swap,pop,pushz,inc,inc,dup,inc,mul,swap,
    sub,prc,pushz,inc,inc,dup,dup,mul,mul,swap,sub,
    prc,pop,inc,prc,pop,pushz,inc,inc,dup,dup,dup,
    inc,add,mul,add,inc,prc,dec,dec,dec,prc,pop
]).


%% peano arithmetic
z(z).
inc(S,s(S)).
dec(s(S),S).

add(z,S,S).
add(s(S),A,O) :- add(S,s(A),O).

sub(S,z,S).
sub(s(S),s(A),O) :- sub(S,A,O).

mul(_,z,z).
mul(z,_,z).
mul(S,s(z),S).
mul(s(z),S,S) :- \+ S = s(z).
mul(A,B,O) :- dec(A,A1), mul(A1,B,O1), add(B,O1,O).

num(0,z).
num(N,s(S)) :- \+ var(N), N> 0, N1 is N -1, num(N1,S).
num(N,s(S)) :- \+ var(S), num(N1,S), N is N1 + 1.

%% basic linked list/cons cells/

nil(nil).
pair(A,B,pair(A,B)).
head(pair(A,_),A).
tail(pair(_,B),B).

pairs([],nil).
pairs([H|T],pair(H,T1)) :- pairs(T,T1).

%% stack machine

run(P,O) :- pairs(P,Pa), nil(S), eval(Pa,S,Oa), stackback(Oa,O),!.

eval(I,S,S) :- nil(I).
eval(I,S,O) :- head(I,H), exec(H,S,O1),!, tail(I,T), eval(T,O1,O).

exec(pushz,S,O) :- z(Z),pair(Z,S,O).
exec(pop,S,O) :- tail(S,O).
exec(inc,S,O) :- pair(A,B,S), inc(A,A1), pair(A1,B,O).
exec(dup,S,O) :- head(S,A), pair(A,S,O).
exec(prc,S,S) :- head(S,A), num(N,A), writef('%n',[N]).
exec(prn,S,S) :- head(S,A), num(N,A), writef('%w',[N]).
exec(dec,S,O) :- pair(A,B,S), dec(A,A1), pair(A1,B,O).
exec(add,S,O) :- pair(A,At,S), pair(B,T,At), add(A,B,AB), pair(AB,T,O).
exec(swap,S,O) :- pair(A,At,S), pair(B,T,At), pair(A,T,Bt), pair(B,Bt,O).
exec(sub,S,O) :- pair(A,At,S), pair(B,T,At), sub(A,B,AB), pair(AB,T,O).
exec(mul,S,O) :- pair(A,At,S), pair(B,T,At), mul(A,B,AB), pair(AB,T,O).
exec(A,_,_) :- writef("Unknown %w\n",[A]), !, fail.

stackback(nil,[]).
stackback(pair(H,T),[H1|T1]) :- num(H1,H),stackback(T,T1).

start :- helloworld(H), run(H,[]).

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply