Coding: Fleeting Thoughts

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

User avatar
AngrySquirrel
Hellish Sex Goddess
Posts: 983
Joined: Sun Feb 10, 2008 10:26 am UTC
Location: The Northpole

Re: Coding: Fleeting Thoughts

Postby AngrySquirrel » Thu Nov 17, 2016 9:06 pm UTC

raudorn wrote: 35% tribal knowledge.

This is the part I don't think I'll ever be able to acquire. I don't know how to be part of communities and I don't know how to ask people for help. I've been conditioned all my life that asking for help is weakness, and if I show weakness, especially in fields that people expect me to fail at, I'm letting my whole assumed gender down.
Putting the fist into pacifist.

they/them/theirs

User avatar
raudorn
Posts: 346
Joined: Mon Jun 13, 2011 11:59 am UTC

Re: Coding: Fleeting Thoughts

Postby raudorn » Thu Nov 17, 2016 10:10 pm UTC

Well, technically learning tribal knowledge doesn't require you to deal with people, only with the code they write. "Tribal" here means something along the lines of domain knowledge, if we allow domain to mean something arbitrarily specific. Could be code style, use of programs/tools, heuristics, rough estimates of parameters, etc. The things I personally learned from colleagues by talking to them is mostly "interesting, but not immediately applicable here" stuff.

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 5497
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Thu Nov 17, 2016 11:00 pm UTC

You can gain a hell of a lot of that kind of knowledge on stack overflow, reading through all the answers and comments, following the links to various blogs, etc. as well as just googling for solutions to problems, and you can find all sorts of forum posts (I believe this site qualifies), blog posts, etc. that can teach you all sorts of new ways to use existing language features and libraries, as well as inspire you to create new solutions to problems (or, more often for me, independently discover things others have discovered, or independently discover solutions worse than the existing). I don't know a programmer that doesn't do this.
Honesty replaced by greed, they gave us the reason to fight and bleed
They try to torch our faith and hope, spit at our presence and detest our goals

User avatar
headprogrammingczar
Posts: 3072
Joined: Mon Oct 22, 2007 5:28 pm UTC
Location: Beaming you up

Re: Coding: Fleeting Thoughts

Postby headprogrammingczar » Thu Nov 17, 2016 11:10 pm UTC

There's always positions that are "do this other thing, also it gets a lot easier if you spend an hour or two programming something". Pretty much any job with Excel is like this, as is system administration or client-side web development (I would wager most javascript programmers don't know any javascript).
<quintopia> You're not crazy. you're the goddamn headprogrammingspock!
<Weeks> You're the goddamn headprogrammingspock!
<Cheese> I love you

User avatar
The Great Hippo
Swans ARE SHARP
Posts: 6834
Joined: Fri Dec 14, 2007 4:43 am UTC
Location: behind you

Re: Coding: Fleeting Thoughts

Postby The Great Hippo » Sat Nov 26, 2016 4:44 am UTC

I had a really cool 'oh duh' moment today (well, at least I thought it was cool).

I was working on my parser with Python; it takes expressions (written as strings) in infix notation, converts them to reverse polish notation, then resolves them. It became useful for me to include comparison operators (">", "<", "==", etc), but since I wanted to deal primarily with integers and floats, I decided to have 'False' and 'True' be 0 and 1.

That's when I noticed, oh -- if I go with that, then an 'AND' statement could be expressed as multiplication ("(x > 0) * (x < 5)" is 'If X is greater than zero AND x is less than 5'). Similarly, OR could be treated as addition...

I guess the cool part was when I remembered that Python evaluates non-zero values as 'True' and zero values as 'False' -- so in some sense, this premise is already baked in?

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 5497
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Sat Nov 26, 2016 5:12 am UTC

XOR would be addition, and then you have modulo 2 arithmetic (aka GF(2)):

a AND b = a * b mod 2
a XOR b = a + b mod 2

(assuming a and b are in the set {0,1})
Honesty replaced by greed, they gave us the reason to fight and bleed
They try to torch our faith and hope, spit at our presence and detest our goals

User avatar
The Great Hippo
Swans ARE SHARP
Posts: 6834
Joined: Fri Dec 14, 2007 4:43 am UTC
Location: behind you

Re: Coding: Fleeting Thoughts

Postby The Great Hippo » Sat Nov 26, 2016 6:56 pm UTC

I had to look up modulo and think about it for a while to figure out why that makes sense, but now I (think) I've got it.

User avatar
chridd
Has a vermicelli title
Posts: 761
Joined: Tue Aug 19, 2008 10:07 am UTC
Location: ...Earth, I guess?
Contact:

Re: Coding: Fleeting Thoughts

Postby chridd » Sun Nov 27, 2016 6:51 am UTC

Thesh wrote:XOR would be addition, and then you have modulo 2 arithmetic (aka GF(2)):

a AND b = a * b mod 2
a XOR b = a + b mod 2

(assuming a and b are in the set {0,1})
That only works if you're actually using modulo 2 arithmetic. My understanding is that The Great Hippo is writing an expression evaluator with normal (non-modular) arithmetic, and using the already-existing (non–modular arithmetic) + and * operations on booleans (expressed as ordinary numbers 0 and 1). With those operations, + isn't XOR; rather, if only non-negative values are used for booleans, then it acts like OR (positive + positive = positive, zero + positive = positive, zero + zero = zero) (although it gives "true" values other than 0 and 1, and if you give it negative values, then there are cases where true + true = false).

If you wanted mod 2 arithmetic like above, you'd have to add some way to do modular arithmetic (whether that's an extra modular addition operator, or a 'mod' operator, or having numbers know that they're supposed to be mod 2), and if you do that, why not just add AND and OR (or special case + to work as OR on booleans)? Or you could use the convention even = false, odd = true; but, either way, OR is more useful than XOR, so it's probably not worth it. (And I'm pretty sure + meaning OR, and multiplication meaning AND, is an existing convention.)

A separate NOT operation would probably be useful, though (or you could do x == 0).
~ chri d. d. /tʃɹɪ.di.di/ (Phonotactics, schmphonotactics) · they (for now, at least) · Forum game scores
mittfh wrote:I wish this post was very quotable...
flicky1991 wrote:In both cases the quote is "I'm being quoted too much!"

Tub
Posts: 309
Joined: Wed Jul 27, 2011 3:13 pm UTC

Re: Coding: Fleeting Thoughts

Postby Tub » Sun Nov 27, 2016 12:26 pm UTC

The Great Hippo wrote:I[..]I decided to have 'False' and 'True' be 0 and 1.

[..]Similarly, OR could be treated as addition...

You can either guarantee that boolean values are 0 and 1, or you can accept any nonzero value as true.

In the first case, addition will violate that guarantee by producing 1+1=2. You need additional logic to turn the result back into 0 or 1.

In the second case, addition can yield false results, e.g.
[-1] OR [1] = false

Other errors can happen due to overflows, e.g. on unsigned 32-bit integer arithmetic the following will hold:
[2^31] OR [2^31] = false
[2^16] AND [2^16] = false

If you're using floats, there are no overflows, but the special values for Infinity will not behave the way you like:
[high number] AND [high number] AND [false] = +Infinity * 0 = NaN
( [low negative number] AND [low negative number] ) OR ([high number] AND [high number]) = -Infinity + +Infinity = NaN
In the first example, NaN should have meant false, in the second, it should have meant true.

In other words, don't try to emulate boolean logic with arithmetic. When the formula has a boolean operator, simulate it using your language's boolean operators. Those already handle all the corner cases, and they're more optimized than any replacement you could come up with.

You still need to track the type of subexpressions in your formulas. Something like (3 < 4) AND sin(42) does not make sense, and you probably want to catch that and throw an error instead of returning sin(42).

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 5497
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Sun Nov 27, 2016 4:33 pm UTC

chridd wrote:
Thesh wrote:XOR would be addition, and then you have modulo 2 arithmetic (aka GF(2)):

a AND b = a * b mod 2
a XOR b = a + b mod 2

(assuming a and b are in the set {0,1})
That only works if you're actually using modulo 2 arithmetic. My understanding is that The Great Hippo is writing an expression evaluator with normal (non-modular) arithmetic, and using the already-existing (non–modular arithmetic) + and * operations on booleans (expressed as ordinary numbers 0 and 1). With those operations, + isn't XOR; rather, if only non-negative values are used for booleans, then it acts like OR (positive + positive = positive, zero + positive = positive, zero + zero = zero) (although it gives "true" values other than 0 and 1, and if you give it negative values, then there are cases where true + true = false).

If you wanted mod 2 arithmetic like above, you'd have to add some way to do modular arithmetic (whether that's an extra modular addition operator, or a 'mod' operator, or having numbers know that they're supposed to be mod 2), and if you do that, why not just add AND and OR (or special case + to work as OR on booleans)? Or you could use the convention even = false, odd = true; but, either way, OR is more useful than XOR, so it's probably not worth it. (And I'm pretty sure + meaning OR, and multiplication meaning AND, is an existing convention.)

A separate NOT operation would probably be useful, though (or you could do x == 0).


Yeah I was half doing something else when I wrote that, and kind of missed the point - I was more concerned with the fact that OR and AND are less useful than XOR and AND - you can construct any boolean operator from XOR and AND, but yes you are right that it needs to be even/odd. Also, unlike zero/positive, using + and * for XOR and AND don't have issues with overflow or negative numbers.

NOT = increment/decrement
OR = a * b + a + b
Honesty replaced by greed, they gave us the reason to fight and bleed
They try to torch our faith and hope, spit at our presence and detest our goals

User avatar
The Great Hippo
Swans ARE SHARP
Posts: 6834
Joined: Fri Dec 14, 2007 4:43 am UTC
Location: behind you

Re: Coding: Fleeting Thoughts

Postby The Great Hippo » Mon Nov 28, 2016 11:05 am UTC

Okay, I think I've got a better grasp of booleans, now (also, I think I finally understand what an integer overflow error is >_>).

The other problem I'm encountering: I use the shunting yard algorithm to turn infix to rpn. I have support for functions -- but only if they accept two values (like most operators). I'm trying to figure out a way to use the output of the shunting yard algorithm to create an rpn that feeds a function all the arguments it's given; in other words, rather than taking the first two values off the stack, the function would eat the whole stack. I'm not sure how to treat functions in the algorithm so that this would produce a valid result, though (it might not even be possible?).

User avatar
phlip
Restorer of Worlds
Posts: 7543
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: Coding: Fleeting Thoughts

Postby phlip » Mon Nov 28, 2016 12:13 pm UTC

Polish notation (either normal or reverse) isn't too hard to extend to add operators that take any fixed number of parameters... but adding functions that take a variable number of parameters is a whole other ballgame.

Chances are, just doing "eat the whole stack" isn't actually what you want... because at some point you're going to want to write "f(1,2,3) + f(4,5,6,7)" and you won't be able to.

There are a few options. One is to add parens back into the mix... eg in Logo, which uses normal Polish notation, where eg:

Code: Select all

product sum 1 2 3
means (1 + 2) * 3, but you can add parens and do:

Code: Select all

product (sum 1 2 3) 4
to do (1 + 2 + 3) * 4. Or you can go full-hog and end up with Lisp, where there are parens around everything, and you end up with a tree that has the same structure as Polish notation, but is parsed completely differently.

Alternatively, there's things like Forth, which uses reverse Polish notation, and does variadic functions by having the first value on the stack be the number of parameters to read. So, if you declared the functions appropriately, you could have:

Code: Select all

2 3 4 5 3 sum 2 product
for 2 * (3 + 4 + 5).

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
Flumble
Yes Man
Posts: 1943
Joined: Sun Aug 05, 2012 9:35 pm UTC

Re: Coding: Fleeting Thoughts

Postby Flumble » Mon Nov 28, 2016 12:22 pm UTC

In programming languages with partial application (or currying or whatever you call it) all functions only take one argument. Except they don't always return a value, but sometimes they return a new function of one argument. (Most notably, the syntax of these languages doesn't use parentheses for evaluating functions: adding 1 and 1 is add 1 1. Unless you have another function inside of course: 10 + add (negate 1) (2+3).)
For example, negate is a function that takes a number and returns a number, so 42 negate (I'm writing it in RPN here) is simply the number -42. Meanwhile, add is a function that naturally takes 2 numbers and returns a number, but with currying it's a function that takes one number and returns a {function that takes one number and returns a number}, so 2 add is a function that takes a number and returns a number, and 40 2 add is 40 (2 add) is again the number 42.
And you can apply this to functions with more arguments too: solveQuadratic (giving some solution of x for ax^2+bx+c=d) is a function that takes a number and returns a {function that takes a number and returns a {function that takes a number and returns a {function that takes a number and returns a number}}}.
What you need for this approach is a way to store partially applied functions on the stack, either by storing a tuple of (function,[argument]) or by actually defining the functions as functions of a function of a function of one argument.

You can generalize your operators to this form, too. Instead of the stack seeing (+) at the top and taking 2 values to calculate the result and pushing a number to the stack, you can also take 1 value from the stack and push partial(+,[value]) to the stack. And then it sees partial(+,[value]) at the top and takes another value from the stack to arrive at partial(+,[value,value]) and since (+) takes 2 arguments, the partial can now be evaluated and return a number.


Or all the curry blabbering aside: what you need for each non-operator function is the knowledge of how many arguments they take. If you see solveQuadratic and it is defined as taking 4 arguments, you pop 4 values from the stack and feed them to the function.
If you don't know how many arguments a function takes, or it's a variadic function, you get into trouble. (In that case, you need some syntax to denote function arguments/n-tuples/lists and be able to put those on the stack as single elements)
Also what phlip says.

User avatar
The Great Hippo
Swans ARE SHARP
Posts: 6834
Joined: Fri Dec 14, 2007 4:43 am UTC
Location: behind you

Re: Coding: Fleeting Thoughts

Postby The Great Hippo » Mon Nov 28, 2016 1:30 pm UTC

Wow; okay, now I finally understand what the point of currying is (I've understood how it works before, but I've never grasped *why* you would do it that way). Also, I actually think I know precisely how to implement variadic functions into the code (and in such a way that it generalizes to operators, too; which means I could have unary operators, if I wanted).

Using parenthesis in rpn would work, but having the number of arguments a function takes on top of the stack when you hit the function seems pretty straightforward to implement at this stage. Thanks!

User avatar
Xeio
Friends, Faidites, Countrymen
Posts: 5086
Joined: Wed Jul 25, 2007 11:12 am UTC
Location: C:\Users\Xeio\
Contact:

Re: Coding: Fleeting Thoughts

Postby Xeio » Thu Dec 01, 2016 9:26 pm UTC

Death to the GAC!

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 5497
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Thu Dec 01, 2016 9:44 pm UTC

Solution: A language that has a standardized canonical encoding format that encodes all functions in a unique fashion so that two functions that differ only in superficial ways will be encoded identically. You then hash the function, and have each program reference functions by their hash. There is no having to deal with getting the wrong version, and when you update the library, you can update the cached binaries to reference the new hash (as long as the function signature remains unchanged).
Honesty replaced by greed, they gave us the reason to fight and bleed
They try to torch our faith and hope, spit at our presence and detest our goals

User avatar
ucim
Posts: 5564
Joined: Fri Sep 28, 2012 3:23 pm UTC
Location: The One True Thread

Re: Coding: Fleeting Thoughts

Postby ucim » Fri Dec 02, 2016 12:35 am UTC

Thesh wrote:...two functions that differ only in superficial ways...
Uhhhh... I'd venture to say that there's no such thing as superficial. Functions make assumptions, and when those assumptions are true, there are rainbows and ponies. When those assumptions are false, there is rain and horseshit, no matter how trivial that assumption might have been. The function is in the weeds.

This, after all, was the basic idea of the DLL, no?

Jose
Order of the Sillies, Honoris Causam - bestowed by charlie_grumbles on NP 859 * OTTscar winner: Wordsmith - bestowed by yappobiscuts and the OTT on NP 1832 * Ecclesiastical Calendar of the Order of the Holy Contradiction * Please help addams if you can. She needs all of us.

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 5497
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Fri Dec 02, 2016 1:02 am UTC

ucim wrote:
Thesh wrote:...two functions that differ only in superficial ways...
Uhhhh... I'd venture to say that there's no such thing as superficial. Functions make assumptions, and when those assumptions are true, there are rainbows and ponies. When those assumptions are false, there is rain and horseshit, no matter how trivial that assumption might have been. The function is in the weeds.


Umm... Of course there are superficial things. That's the entire reason for canonical encodings.
Honesty replaced by greed, they gave us the reason to fight and bleed
They try to torch our faith and hope, spit at our presence and detest our goals

User avatar
The Great Hippo
Swans ARE SHARP
Posts: 6834
Joined: Fri Dec 14, 2007 4:43 am UTC
Location: behind you

Re: Coding: Fleeting Thoughts

Postby The Great Hippo » Fri Dec 02, 2016 2:28 am UTC

I'm looking for feedback on two of my approaches. Keep in mind, still a hobbyist programmer with no real CS background:

I'm toying with an entity-component system. Entities are integers (the identity of an in-game object); components are properties associated with entities ("x", or "y", or "inventory"); systems are code that processes entities with certain components (physics system processes all entities with "x" and "y" components).

Rather than maintaining a list of entities (and associating them with components), I'm maintaining a dictionary of components -- and associating them with entities. In other words:

Code: Select all

player = 1
monster = 2

components = dict()
components["x"] = dict()
components["y"] = dict()

components["x"][player] = 0
components["y"][player] = 1
components["x"][monster] = 2
components["y"][monster] = 5

Every loop, the physics system performs a set intersection across components["x"] and components["y"], then iterates over all the entity ids that are in both.

So, question one: Is that a really bad idea?

The other part of this: Some of my components aren't values, but rather formulas -- and I'd like to define these formulas in a data-driven way (rather than hard-coding them). For example, my "str_bonus" component (strength bonus, for you non-D&D nerds) might be "(entity.strength - 10) / 2".

To facilitate that, I'm writing a parser that evaluates strings (presumed to be infix expressions) and returns a function that, when called, resolves the string and returns the result. The tricky part is that these expressions can contain "pointers" to other components.

Is this also a terrible idea? I think I know how to implement it, but I'm trying to figure out if it might create serious problems down the line. I've got the parser working; it just doesn't return functions, yet (it evaluates the expression immediately).

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 5497
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Fri Dec 02, 2016 2:46 am UTC

The Great Hippo wrote:To facilitate that, I'm writing a parser that evaluates strings (presumed to be infix expressions) and returns a function that, when called, resolves the string and returns the result. The tricky part is that these expressions can contain "pointers" to other components.

Is this also a terrible idea? I think I know how to implement it, but I'm trying to figure out if it might create serious problems down the line. I've got the parser working; it just doesn't return functions, yet (it evaluates the expression immediately).


I would pass various functions around, although the syntax would vary on the language. Here is an example in python:

Code: Select all

def add(a, b):
    return a + b;

x = 1
y = 2
action = add

print action(x,y)
Honesty replaced by greed, they gave us the reason to fight and bleed
They try to torch our faith and hope, spit at our presence and detest our goals

User avatar
The Great Hippo
Swans ARE SHARP
Posts: 6834
Joined: Fri Dec 14, 2007 4:43 am UTC
Location: behind you

Re: Coding: Fleeting Thoughts

Postby The Great Hippo » Fri Dec 02, 2016 3:03 am UTC

I'm probably explaining this poorly (or, alternatively, I'm just failing to understand your suggestion)?

Some components contain simple values. For example, component["x"][player] would probably just contain 0, or 1, or 2. Other components -- like component["str_bonus"][player] -- would be a formula that has to be calculated every time it's retrieved (to know your str_bonus, we need your strength component's value). Basically, it's like python's @property decorator (or its custom __get__ descriptor).

To facilitate this, I'm using a parser that lets me transform strings into functions (functions which are custom-built for each entity). So, component["str_bonus"][player] would contain a special function (built by the parser) that allows it to pull component["strength"][player] and perform some operations on it, then return the result.

This means two things:
  • component["str_bonus"] is probably a custom dictionary that, rather than just returning the value associated with a key, calls that value and returns whatever that callable value returns.
  • The parser needs to know where the components live, and -- when it builds the custom formula-function -- it needs to know which entity we're talking about.
I think my main anxiety with this is that I might end up with circular references (though I think this can be done to avoid that -- without relying on weakrefs), but I'm also just generally anxious that, for some reason, this idea is pretty bad and just ultimately confusing and weird.

EDIT: Well, it also means that I should probably throw a warning or something if you assign a new value to component["str_bonus"][player] -- since this is a formula, and assigning a new value would destroy that formula (but might be useful for testing).

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 5497
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Fri Dec 02, 2016 3:31 am UTC

So, say you have a YAML file like this:

Code: Select all

formula:
    name: str_bonus
    id: player
    - paren
        - entity: strength
        - operator: subtract
        - integer: 10
     - operator: divide
     - integer: 2


Use python to loop through the formulas and properties, and then programmatically build the functions from that by passing functions/objects around.
Honesty replaced by greed, they gave us the reason to fight and bleed
They try to torch our faith and hope, spit at our presence and detest our goals

User avatar
The Great Hippo
Swans ARE SHARP
Posts: 6834
Joined: Fri Dec 14, 2007 4:43 am UTC
Location: behind you

Re: Coding: Fleeting Thoughts

Postby The Great Hippo » Fri Dec 02, 2016 3:49 am UTC

...oh. Huh. Wow. Yeah, that's actually way easier than what I was trying to do with strings and parsing.

Is it weird that I still kind of want to do string-expressions instead? If only because they're nicer/easier to read? But your solution is way more straight to the point.

I will mention that these formulas are meant to be universal to a component; in other words, the 'str_bonus' component is always the same formula no matter which entity it's on (the only real difference, here, is that when it refers to the entity's strength, it's referring to the entity it's currently being accessed from). So these formula-functions don't actually get created until you've given an entity the relevant component. But all that really means on the data-side is that I don't bother assigning an id (since it's assigned dynamically).

User avatar
ucim
Posts: 5564
Joined: Fri Sep 28, 2012 3:23 pm UTC
Location: The One True Thread

Re: Coding: Fleeting Thoughts

Postby ucim » Fri Dec 02, 2016 4:34 am UTC

Thesh wrote:Umm... Of course there are superficial things. That's the entire reason for canonical encodings.

What are canonical encodings?

Jose
Order of the Sillies, Honoris Causam - bestowed by charlie_grumbles on NP 859 * OTTscar winner: Wordsmith - bestowed by yappobiscuts and the OTT on NP 1832 * Ecclesiastical Calendar of the Order of the Holy Contradiction * Please help addams if you can. She needs all of us.

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 5497
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Fri Dec 02, 2016 5:04 am UTC

Canonical means there is one correct way to encode it. So let's say you have this expression:

a*(b+c)-d*((1-e)+f)

Your rules might say that parentheses expressions always go on the left if the operation is commutative, and that redundant parentheses are removed, so no matter how you write it, as long as the pieces not handled by the encoding remain unchanged, it gets encoded like this:

(b+c)*a-(1-e+f)*d

It doesn't necessarily mean all functionally equivalent procedures will be considered identical, but you could also standardize local variable names based on the order in which they appear (function names are a different matter).

EDIT: Not to mention formatting/whitespace, and removing things like comments, expanding macros.
Honesty replaced by greed, they gave us the reason to fight and bleed
They try to torch our faith and hope, spit at our presence and detest our goals

User avatar
chridd
Has a vermicelli title
Posts: 761
Joined: Tue Aug 19, 2008 10:07 am UTC
Location: ...Earth, I guess?
Contact:

Re: Coding: Fleeting Thoughts

Postby chridd » Fri Dec 02, 2016 6:21 am UTC

Thesh wrote:Solution: A language that has a standardized canonical encoding format that encodes all functions in a unique fashion so that two functions that differ only in superficial ways will be encoded identically. You then hash the function, and have each program reference functions by their hash. There is no having to deal with getting the wrong version, and when you update the library, you can update the cached binaries to reference the new hash (as long as the function signature remains unchanged).
What problem is this trying to solve?
~ chri d. d. /tʃɹɪ.di.di/ (Phonotactics, schmphonotactics) · they (for now, at least) · Forum game scores
mittfh wrote:I wish this post was very quotable...
flicky1991 wrote:In both cases the quote is "I'm being quoted too much!"

User avatar
Flumble
Yes Man
Posts: 1943
Joined: Sun Aug 05, 2012 9:35 pm UTC

Re: Coding: Fleeting Thoughts

Postby Flumble » Fri Dec 02, 2016 11:14 am UTC

chridd wrote:
Thesh wrote:Solution: A language that has a standardized canonical encoding format that encodes all functions in a unique fashion so that two functions that differ only in superficial ways will be encoded identically. You then hash the function, and have each program reference functions by their hash. There is no having to deal with getting the wrong version, and when you update the library, you can update the cached binaries to reference the new hash (as long as the function signature remains unchanged).
What problem is this trying to solve?

Probably "every kind of code duplication" and "having to read/write documentation because of semantics" and perhaps solving P=NP, in exchange for problems like "having trillions of black boxes" and "century-long compiling times".

Take a look at Coq if you're interested in finding mathematical/programmatical equivalences.

[pseudoedit] Oops, Thesh's idea doesn't go for equivalences, but merely for a simple sorting-commutative-operations. Simple as in: a+a and 2*a have different encodings.

User avatar
ucim
Posts: 5564
Joined: Fri Sep 28, 2012 3:23 pm UTC
Location: The One True Thread

Re: Coding: Fleeting Thoughts

Postby ucim » Fri Dec 02, 2016 2:16 pm UTC

Thesh wrote:[canonical encoding] doesn't necessarily mean all functionally equivalent procedures will be considered identical...
In that case, what's the point? As to re-ordering of operations, the compiler may (or may not - depends) for example treat (ab-ac) and (a-b)*c differently. One might be easier to understand reading the code, but the other may break less frequently in edge cases. So, do they differ in "superficial" ways?

Jose
Order of the Sillies, Honoris Causam - bestowed by charlie_grumbles on NP 859 * OTTscar winner: Wordsmith - bestowed by yappobiscuts and the OTT on NP 1832 * Ecclesiastical Calendar of the Order of the Holy Contradiction * Please help addams if you can. She needs all of us.

Tub
Posts: 309
Joined: Wed Jul 27, 2011 3:13 pm UTC

Re: Coding: Fleeting Thoughts

Postby Tub » Fri Dec 02, 2016 3:23 pm UTC

A canonical representation will not catch all functional identical formulas, but many. Consider it a "best effort" solution.
For compilers, one use for a canonical representation is common subexpression elimination - without a canonical form, many optimization opportunities would be overlooked.

More generally, a canonical form is useful everytime you want to cache intermediate results of expressions. For example, we work with a database query language, and by canonicalizing the subexpressions before hitting the cache, our cache hit rate improves substantially.

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 5497
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Fri Dec 02, 2016 4:13 pm UTC

chridd wrote:
Thesh wrote:Solution: A language that has a standardized canonical encoding format that encodes all functions in a unique fashion so that two functions that differ only in superficial ways will be encoded identically. You then hash the function, and have each program reference functions by their hash. There is no having to deal with getting the wrong version, and when you update the library, you can update the cached binaries to reference the new hash (as long as the function signature remains unchanged).
What problem is this trying to solve?


It solves one of the annoyances with the Global Assembly Cache (e.g. having to load assemblies into the cache so different applications can share them) in the most heavy-handed manner I could think of.
Honesty replaced by greed, they gave us the reason to fight and bleed
They try to torch our faith and hope, spit at our presence and detest our goals

User avatar
Yakk
Poster with most posts but no title.
Posts: 11045
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Coding: Fleeting Thoughts

Postby Yakk » Fri Dec 02, 2016 4:46 pm UTC

It would be easier to just solve Halt.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

commodorejohn
Posts: 957
Joined: Thu Dec 10, 2009 6:21 pm UTC
Location: Placerville, CA
Contact:

Re: Coding: Fleeting Thoughts

Postby commodorejohn » Fri Dec 02, 2016 6:10 pm UTC

Thesh wrote:Solution: A language that has a standardized canonical encoding format that encodes all functions in a unique fashion so that two functions that differ only in superficial ways will be encoded identically. You then hash the function, and have each program reference functions by their hash. There is no having to deal with getting the wrong version, and when you update the library, you can update the cached binaries to reference the new hash (as long as the function signature remains unchanged).

That's called a CPU instruction set.
"'Legacy code' often differs from its suggested alternative by actually working and scaling."
- Bjarne Stroustrup
www.commodorejohn.com - in case you were wondering, which you probably weren't.

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 5497
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Fri Dec 02, 2016 6:16 pm UTC

I mean, if you ignore that machine language is not canonical, and if you don't care about compiler optimizations, then sure, that works perfectly for what I just described.
Honesty replaced by greed, they gave us the reason to fight and bleed
They try to torch our faith and hope, spit at our presence and detest our goals

commodorejohn
Posts: 957
Joined: Thu Dec 10, 2009 6:21 pm UTC
Location: Placerville, CA
Contact:

Re: Coding: Fleeting Thoughts

Postby commodorejohn » Fri Dec 02, 2016 6:49 pm UTC

Any individual machine language is canonical, there are just a lot of them. And optimizations occur between different CPU models/revisions.
"'Legacy code' often differs from its suggested alternative by actually working and scaling."
- Bjarne Stroustrup
www.commodorejohn.com - in case you were wondering, which you probably weren't.

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 5497
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Fri Dec 02, 2016 6:53 pm UTC

Great, so no matter what optimization settings I use, and what compiler I use, if I give it the same input I will always get the exact same output? Good to know!
Honesty replaced by greed, they gave us the reason to fight and bleed
They try to torch our faith and hope, spit at our presence and detest our goals

commodorejohn
Posts: 957
Joined: Thu Dec 10, 2009 6:21 pm UTC
Location: Placerville, CA
Contact:

Re: Coding: Fleeting Thoughts

Postby commodorejohn » Fri Dec 02, 2016 7:01 pm UTC

If you generate the same sequence of machine instructions for the same machine language, yes, you'll get the same output for the same input. That's the entire point of having them.

And if you use an optimizing assembler that generates some other sequence of machine instructions than what you specified, well, that's your problem.
"'Legacy code' often differs from its suggested alternative by actually working and scaling."
- Bjarne Stroustrup
www.commodorejohn.com - in case you were wondering, which you probably weren't.

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 5497
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Fri Dec 02, 2016 7:13 pm UTC

commodorejohn wrote:If you generate the same sequence of machine instructions for the same machine language, yes, you'll get the same output for the same input. That's the entire point of having them.


The machine instructions ARE the output of a compiler. Understand that the purpose of the global assembly cache is to create an IO-efficient repository for shared assemblies. You have to have a standardized way to represent a function so that you can hash it (where there is a trade-off between the strictness of your encoding rules, and the likelihood that the same function written by two different people will get encoded to the same canonical form and thus reduce memory consumption). Since there are no explicit rules for compiling from a high level language to a machine language (i.e. you have to interpret each spec independently, and figure out the exact translations yourself), it is useless for this purpose.
Honesty replaced by greed, they gave us the reason to fight and bleed
They try to torch our faith and hope, spit at our presence and detest our goals

User avatar
Qaanol
The Cheshirest Catamount
Posts: 3035
Joined: Sat May 09, 2009 11:55 pm UTC

Re: Coding: Fleeting Thoughts

Postby Qaanol » Sat Dec 03, 2016 4:52 am UTC

Yakk wrote:It would be easier to just solve Halt.

Every program terminates, even the ones with unconditional loops.

You are welcome.
wee free kings

User avatar
Xenomortis
Not actually a special flower.
Posts: 1396
Joined: Thu Oct 11, 2012 8:47 am UTC

Re: Coding: Fleeting Thoughts

Postby Xenomortis » Sun Dec 04, 2016 11:18 am UTC

To be fair, I will definitely press Ctrl-C after a while.
Image

User avatar
Flumble
Yes Man
Posts: 1943
Joined: Sun Aug 05, 2012 9:35 pm UTC

Re: Coding: Fleeting Thoughts

Postby Flumble » Sun Dec 04, 2016 12:45 pm UTC

Yay, I'm finally starting to get comfortable with docker. That is to say, from the start I had a clear picture of the services and interconnects that are needed, but a lot of containers have their own finicky way to specify how to connect to another container/run behind a proxy.

Last in line is getting CODE to work within nextcloud. The worst part is I can't find any logs. :shock: (of course there's the stdout a.k.a. docker logs, but all of caddy, nextcloud and code only tell "this service has started" :( )
Caddy says it gets an EOF or 502 from the CODE container (04/Dec/2016:12:16:33 +0000 [ERROR 502 /hosting/discovery] EOF) and responds with a 502 to the internet.

This is what the relevant configuration looks like:
Spoiler:
docker-compose.yml

Code: Select all

  caddy:
    image: abiosoft/caddy
    restart: always
    environment:
      CADDYPATH: "/etc/caddycerts"
    volumes:
      - ./Caddyfile:/etc/Caddyfile
      - caddy-certs:/etc/caddycerts
      - caddy-web:/srv
    ports:
      - "80:80"
      - "443:443"

  nextcloud:
    image: wonderfall/nextcloud
    restart: always
    depends_on:
      - nextcloud-db
    environment:
      - UID=1000
      - GID=1000
      - UPLOAD_MAX_SIZE=10G
      - APC_SHM_SIZE=128M
      - OPCACHE_MEM_SIZE=128
      - REDIS_MAX_MEMORY=64mb
      - CRON_PERIOD=15m
      - TZ=Europe/Amsterdam
      - ADMIN_USER=<somenameB>
      - ADMIN_PASSWORD=<somepasswordB>
      - DB_TYPE=mysql
      - DB_NAME=<somedbA>
      - DB_USER=<somenameA>
      - DB_PASSWORD=<somepasswordA>
      - DB_HOST=nextcloud-db
    depends_on:
      - nextcloud-db
    volumes:
      - nextcloud-data:/data
      - nextcloud-config:/config
      - nextcloud-apps:/apps2

  collabora:
    image: collabora/code
    restart: always
    depends_on:
      - nextcloud
    environment:
      domain: "nextcloud\\.<somedomainA>"
    cap_add:
      - MKNOD
    expose:
      - "9980"

  nextcloud-db:
    image: mariadb
    restart: always
    volumes:
      - nextcloud-db-data:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=<somepasswordC>
      - MYSQL_DATABASE=<somedbA>
      - MYSQL_USER=<somenameA>
      - MYSQL_PASSWORD=<somepasswordA>

Caddyfile:

Code: Select all

nextcloud.<somedomainA> {
        proxy / http://nextcloud:8888 {
                transparent
        }
}

collabora.<somedomainA> {
        errors stdout #for the bug porpoises
        log stdout #for the bug porpoises

        proxy / collabora:9980 {
                transparent
                websocket
        }
}


Collabora online 1.1.15 app setting:
Server: https://collabora.<somedomainA>


(why post this in FT? I don't know; I should probably ask on nextcloud's/collabora's help place, too)


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 6 guests