Coding: Fleeting Thoughts

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

Moderators: phlip, Moderators General, Prelates

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

Re: Coding: Fleeting Thoughts

Postby The Great Hippo » Tue Apr 21, 2015 4:46 pm UTC

Xanthir wrote:Unless there is a distinguished point (the origin) in which case they're identical again.

Even if its not canonically meaningful, most graphics software pretends there's a distinguished point, and so treats points and vectors as identical, with homogenous coordinates distinguishing them.

ETA: Never mind, I confused myself. Homogenous coordinates lets people treat vectors/points and *directions* the same. Points are vectors just by convention, even if it's nonsensical. Points are never *treated as* vectors (I hope...) but they're represented as vectors because there's no arithmetic difference between them as long as you don't perform the meaningless operations.
Panda3D -- an open-source 3D scene graph engine for Python -- differentiates between vectors and points, which is probably where I got the notion stuck in my head that this is a very important distinction to make.

And maybe it is -- in 3D engines! But since I'm not building a 3D engine, I can probably afford to not care. >.>

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

Re: Coding: Fleeting Thoughts

Postby Yakk » Tue Apr 21, 2015 4:56 pm UTC

Xenomortis wrote:
Yakk wrote:Did you mean no arithmatic difference?

In En - his coordinate spaces.

Did you mean Rn? Because E is ... well, a symbol out of left field?
Xanthir wrote:Unless there is a distinguished point (the origin) in which case they're identical again.

Yep: fp0(p) = p-p0 embeds a Euclidean affine space into a vector space.

In my experience, treating points as vectors is really common. Hence the utility in putting them in separate spaces, and forcing an explicit transformation into a chosen vector space.

The downside is that the affine combination -- z = sum lambda_i p_i where sum lambda_i is 1 -- is not something that is naturally written in most programming languages (whose operators tend to be at most binary). And the check (that the coefficients sum to 1, or at least non-zero) is a lot like the check for division (that the denominator isn't 0), a source of possible exceptions (or whatever error handling).

So even if you have a point-vector split, your point type tends to have "scale by scalar x" and "add two points together" to make things like "the average point" (a valid operation on points) easier to express. Which gets rid of half of the type-safety barriers.

Re: no cross product in R2:
Spoiler:
And it isn't at all common for type systems to distinguish between a x b's space and a's and b's space -- see http://en.wikipedia.org/wiki/Exterior_algebra . (That is why a "cross product" of two R2 vectors is valid -- it is a scalar, a member of R1, whose (signed) magnitude is equal to |a||b| sin ab).

This also happens to be the (signed) length of the vector you get if you embed the 2-dimensional vectors in R3, then do a traditional cross product.

In R4, the wedge product gives us an element of R4 choose 2 = R6. Another vector in the product makes it 4 choose 3, aka R4. 4 vectors makes it a signed 4-volume (the 4-volume of the 4-dimensional 4-"parallelogram" defined by the 4 vectors) in R1.

Basically when you split vectors and points, you catch some errors "early". It is really easy to accidentally treat a point as a vector, and basically never right.

As a bonus, you can sometimes get a payoff from this.

Suppose you have an affine transformation on a point space.

Applying it to a point, it can cause rotations, translations and the like.

But applying it to a vector, the translations should be ignored. And if you are using a standard 4x3 matrix (or is it 4x4, I forget?) for your affine transformation, ignoring the parts that don't apply to a vector is easy.

If you distinguish between these two types, you can save boilerplate conditions in some spots.
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.

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

Re: Coding: Fleeting Thoughts

Postby Xenomortis » Tue Apr 21, 2015 5:27 pm UTC

Yakk wrote:
Xenomortis wrote:
Yakk wrote:Did you mean no arithmatic difference?

In En - his coordinate spaces.

Did you mean Rn? Because E is ... well, a symbol out of left field?

En - n dimensional Euclidean space?
i.e. Rn with the usual Euclidean nature.
Image

Ubik
Posts: 1016
Joined: Thu Oct 18, 2007 3:43 pm UTC

Re: Coding: Fleeting Thoughts

Postby Ubik » Tue Apr 21, 2015 5:35 pm UTC

The Great Hippo wrote:Panda3D -- an open-source 3D scene graph engine for Python -- differentiates between vectors and points, which is probably where I got the notion stuck in my head that this is a very important distinction to make.

And maybe it is -- in 3D engines! But since I'm not building a 3D engine, I can probably afford to not care. >.>
Funny thing is, in GLSL - the OpenGL shading language - points and vectors and generally anything with 2, 3 or 4 numeric components are represented by datatypes vec2, vec3 and vec4. Of course, OpenGL is a graphics API and not an engine, but still. HLSL, the language used with Direct3D, uses more generic float2, float3 and float4.

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

Re: Coding: Fleeting Thoughts

Postby phlip » Wed Apr 22, 2015 12:45 am UTC

In a more typesafe language (I'm looking at you, Haskell) you could afford to have different types for Point and Vector, even if the actual operations over them are the same code, you get some free type-checking. Or if there's some aspect of the difference between points and vectors that's relevant to the code (eg in Python, datetime and timedelta are different types because month-lengths and leap-years complicate timedelta calculations... or in C, pointers and ints behave like points and vectors, and it makes sense for them to be different types, since you can't dereference the vector type).

But if you're in Python duck-typing land anyway, and there isn't any real fundamental difference between the two types, there's not much to be gained IMO. Just pick an origin and use vectors for everything.

Code: Select all

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

User avatar
rath358
The bone of my bone
Posts: 945
Joined: Wed Jan 14, 2009 6:02 am UTC
Location: west Camberville

Re: Coding: Fleeting Thoughts

Postby rath358 » Thu Apr 23, 2015 4:04 am UTC

My roommate discovered that the latency between two nodes A and B on his network is O(log(A xor B))
I have never seen, or even imagined, an xor in big O notation.

User avatar
ahammel
My Little Cabbage
Posts: 2135
Joined: Mon Jan 30, 2012 12:46 am UTC
Location: Vancouver BC
Contact:

Re: Coding: Fleeting Thoughts

Postby ahammel » Thu Apr 23, 2015 4:15 am UTC

rath358 wrote:an xor
So not everybody pronounces that word "zor", eh?
He/Him/His/Alex
God damn these electric sex pants!

User avatar
Xanthir
My HERO!!!
Posts: 5426
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Thu Apr 23, 2015 4:55 am UTC

No, its "ex-or", obviously.
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

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

Re: Coding: Fleeting Thoughts

Postby Xenomortis » Thu Apr 23, 2015 8:53 am UTC

Or "ksor".

(Although I'm in the "zor" camp myself")
Image

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

Re: Coding: Fleeting Thoughts

Postby Yakk » Thu Apr 23, 2015 1:56 pm UTC

In Python, if I remember correctly, variables storing types are (smart) pointers, and assignment replaces the pointer? A big advantage of typed vectors/points is that you can have variables designated as a vector or a point, with errors generated if they mismatch.

Ie, the usual problem of languages that don't really support value-types.

You'd have to use `.assign( rhs )` style python to assign over things. And that isn't very pythonic.

Still, at least you can get errors on "a+b" where both a and b are points.
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.

moiraemachy
Posts: 190
Joined: Wed Jan 04, 2012 9:47 pm UTC

Re: Coding: Fleeting Thoughts

Postby moiraemachy » Fri Apr 24, 2015 2:56 am UTC

Xanthir wrote:No, its "shor", obviously.
FTFY

User avatar
ahammel
My Little Cabbage
Posts: 2135
Joined: Mon Jan 30, 2012 12:46 am UTC
Location: Vancouver BC
Contact:

Re: Coding: Fleeting Thoughts

Postby ahammel » Fri Apr 24, 2015 3:34 am UTC

throat-clearing-noise-or
He/Him/His/Alex
God damn these electric sex pants!

User avatar
Sizik
Posts: 1260
Joined: Wed Aug 27, 2008 3:48 am UTC

Re: Coding: Fleeting Thoughts

Postby Sizik » Fri Apr 24, 2015 3:42 am UTC

x̶̵̢̲̰̮̯̪͔̞̟̟̫̗̭͈͔͒͑ͤ̋ͮ͆̉̐ͬ̇̑͛͋̈́͞or
she/they
gmalivuk wrote:
King Author wrote:If space (rather, distance) is an illusion, it'd be possible for one meta-me to experience both body's sensory inputs.
Yes. And if wishes were horses, wishing wells would fill up very quickly with drowned horses.

User avatar
PM 2Ring
Posts: 3715
Joined: Mon Jan 26, 2009 3:19 pm UTC
Location: Sydney, Australia

Re: Coding: Fleeting Thoughts

Postby PM 2Ring » Fri Apr 24, 2015 6:04 am UTC

A discussion about points and vectors wouldn't be complete without mentioning torsors.
John Baez wrote:Whenever I teach students about vectors they find this stuff very confusing. The reason is that we're using vectors in two different ways. If your teacher didn't explain this stuff well, call them up and tell them "You should have told us about torsors!"



Yakk wrote:In Python, if I remember correctly, variables storing types are (smart) pointers, and assignment replaces the pointer? A big advantage of typed vectors/points is that you can have variables designated as a vector or a point, with errors generated if they mismatch.

Ie, the usual problem of languages that don't really support value-types.

You'd have to use `.assign( rhs )` style python to assign over things. And that isn't very pythonic.

Still, at least you can get errors on "a+b" where both a and b are points.


You can define a Points class and a Vector class in Python and give them methods that let you perform appropriate operations with them; by using special "magic" method names (double underscore, aka dunder methods) you can even invoke those operations using the usual '+', '-' & '*' operators, if you want. And if a caller attempts an operation that doesn't make sense then you can raise (throw) an appropriate exception.

Of course, if you wish to permit addition of two points your code could silently convert one of the points to a position vector, but many Pythonistas prefer to be explicit about such things, so they expect the caller to perform such a conversion explicitly (via a method call or by passing the point to the vector constructor).

Variables and assignment in Python work a little differently to what you're probably used to in many other languages. Python variable names aren't names of (possibly typed) storage locations. They're simply labels that are bound to objects. This is implemented by using the name as a key in a dictionary (i.e. an associative array / hash table) with the (reference to the) object as the associated value.

Here's a great article on how names work in Python: Facts and myths about Python names and values.

It's quite common practice in Python to take an object, do some calculation with it (sometimes mutating the original object but often creating a new object) and associating the result with the original name, even if the new object has a radically different type to the the original object. Here's a slightly contrived example:

Code: Select all

#Initialise data with a string 
data = '1 2 3 4 5'
#Split the string on whitespace, creating a list of strings
data = data.split()
#Convert the list of strings to a list of integer
data = [int(s) for s in data]
#Add the integers in the list, returning a single integer object
data = sum(data)
 

moiraemachy
Posts: 190
Joined: Wed Jan 04, 2012 9:47 pm UTC

Re: Coding: Fleeting Thoughts

Postby moiraemachy » Fri Apr 24, 2015 8:15 pm UTC

What Yakk is saying is that while you can make (point_b + point_c) throw TypeError, you can't make (point_a = vector_b) do the same, because the name (lvalue?) point_a doesn't have a type.

In theory, this could be implemented in python by allowing the "=" operator to be overloaded, but stackoverflow tells me it's not possible. I guess the reasoning behind this is that "=" is a "fundamental" operator in python, so messing with it would be confusing.

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

Re: Coding: Fleeting Thoughts

Postby Yakk » Fri Apr 24, 2015 8:49 pm UTC

There is <<= style coding for assignment (read it as "put it there") I think.

At least it's an operator.

(Basically, being able to assert to the reader of a chunk of code that a given variable will obey certain invariants throughout the block of code is a useful concept that python lacks, because any constraints you code get thrown out the window the moment you assign to a variable. You can do such constraint checks at particular spots -- like when arguments are passed to a function -- but I'm not a aware of a way to inject it into a non-member variable such that the constraint check occurs at all assignment points. This seems to be a side effect of python (like many languages -- Java, C#, etc) not doing values (at least not of object type).)
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.

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

Re: Coding: Fleeting Thoughts

Postby The Great Hippo » Fri Apr 24, 2015 10:16 pm UTC

The problem you're describing reminds me a little bit of this solution for a python puzzle. Essentially:
Nyktos wrote:Oh hell. I see it.
Spoiler:
Something like this, yes?

Code: Select all

class Foo(object):

    def __del__(self):
        global x
        x = 0


x = Foo()
x = 1
print x

That is pure evil right there. It also won't work (deterministically) on non-refcounting implementations like PyPy.
...which makes me think you could use a similar technique to 'jury-rig' constraints on variables (by assigning them to objects that do insidious shit when you try to delete them). Dunno if that would work, though (and it's definitely very unpythonic!).

schapel
Posts: 244
Joined: Fri Jun 13, 2014 1:33 am UTC

Re: Coding: Fleeting Thoughts

Postby schapel » Fri Apr 24, 2015 10:19 pm UTC

Yakk wrote:(Basically, being able to assert to the reader of a chunk of code that a given variable will obey certain invariants throughout the block of code is a useful concept that python lacks, because any constraints you code get thrown out the window the moment you assign to a variable. You can do such constraint checks at particular spots -- like when arguments are passed to a function -- but I'm not a aware of a way to inject it into a non-member variable such that the constraint check occurs at all assignment points. This seems to be a side effect of python (like many languages -- Java, C#, etc) not doing values (at least not of object type).)

Python doesn't have static type checking, so you're right that you can't express the idea that a variable will always satisfy some property -- you can always assign any value whatsoever to any variable at any place in a Python program. But Java is statically typed, so you can ensure, for example, that a variable is guaranteed to point to a certain type of object, so that the methods of that type (class or interface) will be available.

Nyktos
Posts: 138
Joined: Mon Mar 02, 2009 4:02 pm UTC

Re: Coding: Fleeting Thoughts

Postby Nyktos » Sat Apr 25, 2015 2:44 am UTC

The Great Hippo wrote:...which makes me think you could use a similar technique to 'jury-rig' constraints on variables (by assigning them to objects that do insidious shit when you try to delete them). Dunno if that would work, though (and it's definitely very unpythonic!).
That won't work if you end up with other references to those objects, though. Fundamentally the problem is what Yakk is describing: "variables" in Python are not things, they are names for things. Rebinding a name does not (directly) cause the underlying object to be destroyed. In some implementations it may not "touch" the object at all. In CPython it decrements a reference count, which causes the destruction to be deterministic so long as cycles aren't created, but that's not something that should be relied upon.

Personally I find this conceptually cleaner than the model in (for instance) C++, but it does mean that trying to enforce constraints on a variable (as opposed to on an object) is more or less impossible. The idea of overloading the assignment operator doesn't make any sense in Python's model, because rebinding a name is an an operation on the namespace the code is running in, not on the object to which that name currently refers. In fact you can change the behaviour of the assignment statement in certain contexts, by changing out the namespace object. In particular, import hooks allow you to do this at module scope, and in Python 3 metaclasses let you do it at class scope. There's no way to do it at function scope, which is probably for the best since it allows implementations to not make a hash table lookup every time you use a local variable.

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

Re: Coding: Fleeting Thoughts

Postby Yakk » Sat Apr 25, 2015 8:57 pm UTC

schapel wrote:
Yakk wrote:(Basically, being able to assert to the reader of a chunk of code that a given variable will obey certain invariants throughout the block of code is a useful concept that python lacks, because any constraints you code get thrown out the window the moment you assign to a variable. You can do such constraint checks at particular spots -- like when arguments are passed to a function -- but I'm not a aware of a way to inject it into a non-member variable such that the constraint check occurs at all assignment points. This seems to be a side effect of python (like many languages -- Java, C#, etc) not doing values (at least not of object type).)

Python doesn't have static type checking, so you're right that you can't express the idea that a variable will always satisfy some property -- you can always assign any value whatsoever to any variable at any place in a Python program.

I wasn't talking about static type checking. Imagine Python, but with the ability to annotate a given variable such that a certain test is performed on it whenever an object is assigned to it. You could go even further, and have the test be run whenever the variable is passed to a function, or returned from a function. Heck, while the object is referred to by the variable, whenever that object is mutated, have the test run.

None of these require static type checking. All would be doable in a python-esque language. Some would be more efficient than others.

A check at assignment, when using the variable (both before and after a function call), would catch some categories of errors far earlier. It might even be possible (without hacking the python interpreter that is), I don't know.

---

Nyktos, in C++ variables are names for things. The thing they are a name for never changes (so long as it exists) in its fundamental nature. That thing can be a *pointer* to another thing if you want. A reference is an alternative name for a thing, and similarly what it refers to never changes (so long as the reference and the thing exists). All of this is "modulo undefined behavior", which is behavior outside of that mandated by the C++ standard. There are also some really low level monkey work you can do, spoiler follows

Spoiler:

Code: Select all

    struct foo {
      int& bar;
      foo(int* p):bar(*p);
    };

foo contains a reference (alternative name for) what its constructor is passed. So foo f(&x); f.bar is an alternative name for x.

You can do this:

Code: Select all

  int x;
  foo f(&x);
  f.~foo();
  int y;
  new (&f) foo(&y);

and I now have taken the reference f.bar and changed what it refers to. I did this by ending its lifetime (f.~foo()), then creating a new instance of foo in its place (the funny new call).

I believe that this is completely standards compliant.

This kind of thing is seriously monkey games, and not something you find outside of narrow code bases (like boost::variant, which creates a discriminating union without support from union). About the only justification I can think of for the above is because you want to extend the language with a new kind of primitive. I just include this spoiler to make the "references always refer to the same thing" point clear, namely "so long as they and the thing exist" -- you can end the lifetime of a thing before the variable naming it dies.
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.

User avatar
PM 2Ring
Posts: 3715
Joined: Mon Jan 26, 2009 3:19 pm UTC
Location: Sydney, Australia

Re: Coding: Fleeting Thoughts

Postby PM 2Ring » Sun Apr 26, 2015 7:14 am UTC

Yakk wrote:I wasn't talking about static type checking. Imagine Python, but with the ability to annotate a given variable such that a certain test is performed on it whenever an object is assigned to it. You could go even further, and have the test be run whenever the variable is passed to a function, or returned from a function. Heck, while the object is referred to by the variable, whenever that object is mutated, have the test run.

None of these require static type checking. All would be doable in a python-esque language. Some would be more efficient than others.

A check at assignment, when using the variable (both before and after a function call), would catch some categories of errors far earlier. It might even be possible (without hacking the python interpreter that is), I don't know.

Yeah, ok. I mostly write in Python these days, but I was writing in strongly-typed languages decades before I learned weakly-typed languages like JavaScript, awk, and Python, so I do understand the benefits of type checking. OTOH, the lack of type checking in Python is counter-balanced by the benefits of duck-typing. IMHO.

Doing what you suggest in the first paragraph wouldn't be impossible, but it would conceptually change the nature of Python variables, and I'm not sure that the benefits would justify such a change. As I alluded to earlier, we don't really have variable assignment in Python, although it's often convenient to use such nomenclature, especially for those of us coming from other languages. A Python assignment statement doesn't store an object (or a reference to the object) in a named location, it merely associates a dictionary key with that object. To implement the kind of typing scheme you envisage would merely require attaching (possibly optional) type info to the dictionary key.

FWIW, there actually is a typing scheme for Python, but at this stage it's purely informational, so it doesn't have the full power of the scheme you propose. From PEP 484 - Type Hints:
Abstract

This PEP introduces a standard syntax for type hints using annotations ( PEP 3107 ) on function definitions. For example, here is a simple function whose argument and return type are declared in the annotations:

Code: Select all

def greeting(name: str) -> str:
    return 'Hello ' + name

While these annotations are available at runtime through the usual __annotations__ attribute, no type checking happens at runtime. Instead, the proposal assumes the existence of a separate off-line type checker which users can run over their source code voluntarily. Essentially, such a type checker acts as a very powerful linter.

[...]

Rationale and Goals

PEP 3107 added support for arbitrary annotations on parts of a function definition. Although no meaning was assigned to annotations then, there has always been an implicit goal to use them for type hinting, which is listed as the first possible use case in said PEP.

This PEP aims to provide a standard syntax for type annotations, opening up Python code to easier static analysis and refactoring, potential runtime type checking, and performance optimizations utilizing type information.

Of these goals, static analysis is the most important. This includes support for off-line type checkers such as mypy, as well as providing a standard notation that can be used by IDEs for code completion and refactoring.

User avatar
rath358
The bone of my bone
Posts: 945
Joined: Wed Jan 14, 2009 6:02 am UTC
Location: west Camberville

Re: Coding: Fleeting Thoughts

Postby rath358 » Mon Apr 27, 2015 10:32 am UTC

Code: Select all

    /// @todo CHECK IF $THING1 HAS $THING2
    /// @todo READ THIS TODO!

This fucking project...

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

Re: Coding: Fleeting Thoughts

Postby Flumble » Mon Apr 27, 2015 12:08 pm UTC

@todos are very useful, because they show up in a list in your IDE (so you have your shopping list visible at all times) and you place them within the code (so you know where to continue after a visit to the mall). :D
I did actually use them for RFCs and questions in a previous project.

It's more portable than an issue tracker, but you have to prioritize using caps and exclamation marks.

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

Re: Coding: Fleeting Thoughts

Postby Xeio » Mon Apr 27, 2015 2:30 pm UTC

Code: Select all

//Remove any existing state key entry to prevent errors when setting the state value
state.Remove(StateKeys.LAUNCH_VIEWONLY);
//Set the satte key entry to launch views in full access mode
state[StateKeys.LAUNCH_VIEWONLY] = false;
state.Remove(StateKeys.LAUNCH_VIEWONLY);
Do I even need to note that setting a state key like that won't cause an duplicate key exception, or that the state doesn't have side effects so the 1st and 2nd lines of code are redundant?

Nyktos
Posts: 138
Joined: Mon Mar 02, 2009 4:02 pm UTC

Re: Coding: Fleeting Thoughts

Postby Nyktos » Tue Apr 28, 2015 5:59 am UTC

Yakk wrote:Nyktos, in C++ variables are names for things. The thing they are a name for never changes (so long as it exists) in its fundamental nature. That thing can be a *pointer* to another thing if you want. A reference is an alternative name for a thing, and similarly what it refers to never changes (so long as the reference and the thing exists). All of this is "modulo undefined behavior", which is behavior outside of that mandated by the C++ standard. There are also some really low level monkey work you can do, spoiler follows
I'm far from an expert on C++, but the way I'd characterize things in C is that a variable is a name for a place, rather than a name for an object. I think that's a better way to put it than what I said before. A reassignment modifies the contents of that place, rather than changing what the name actually refers to. C++ references, as I understand them, allow there to be two names for the same place, but nonetheless names map to places (which contain objects) rather than mapping directly to objects.

PM 2Ring wrote:A Python assignment statement doesn't store an object (or a reference to the object) in a named location, it merely associates a dictionary key with that object. To implement the kind of typing scheme you envisage would merely require attaching (possibly optional) type info to the dictionary key.
The problem is that most Python implementations don't actually store local variables in a dictionary, because that would be slow. Implementations are more or less priced into treating module and class namespaces as dictionaries because there are ways to access or even replace these objects, but there is a noticeable lack of similar things at function scope. (For instance, one can use locals() to get a dictionary mapping local names to values, but the result of mutating that dictionary is one of the few cases of unspecified behaviour in Python. On the other hand, modifying the dictionary returned by globals() is specified as causing changes to the module namespace.)

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

Re: Coding: Fleeting Thoughts

Postby raudorn » Tue Apr 28, 2015 6:17 pm UTC

Image

After I added 3k lines to replace them. Still, we got 2k less lines, centralized functionality, expanded features and less bugs. I call that a win.

Rysto
Posts: 1460
Joined: Wed Mar 21, 2007 4:07 am UTC

Re: Coding: Fleeting Thoughts

Postby Rysto » Fri May 01, 2015 11:13 pm UTC

Is it a bad sign when you home directory contains a subdirectory called tmp/tmp?

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

Re: Coding: Fleeting Thoughts

Postby raudorn » Sat May 02, 2015 10:28 am UTC

Rysto wrote:Is it a bad sign when you home directory contains a subdirectory called tmp/tmp?


So long as you don't confuse

Code: Select all

rm -Rf /tmp/.
with

Code: Select all

rm -Rf ./tmp/.
, should be fiiiiine.

Rysto
Posts: 1460
Joined: Wed Mar 21, 2007 4:07 am UTC

Re: Coding: Fleeting Thoughts

Postby Rysto » Sat May 02, 2015 2:14 pm UTC

I was more getting at, is it a bad thing that I have so much crap in ~/tmp, some of which may be important, so I had to create ~/tmp/tmp to store temporary files?

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Sat May 02, 2015 5:53 pm UTC

I frequently, when faced with a lot of junk in ~, create ~junk. I may already have ~junk, which in that case becomes ~junk/junk. Rinse and repeat, and receive the Matryoshka doll that is the 15 years of ~junk-directories I've created. It's like junk/crap/junk/crap/crap/slask/junk/crap/bla/crap/junk at this point.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

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

Re: Coding: Fleeting Thoughts

Postby Thesh » Sat May 02, 2015 6:01 pm UTC

What I do is every so often when I install a new OS, or get a new laptop, I make a backup of ~, which I then allow myself to have a completely clean ~ directory with a folder containing my old ~ directory (although I still move stuff I want to the appropriate location in ~), which also has a folder containing the old ~ directory from the previous system. Right now I'm only like four deep.
Summum ius, summa iniuria.

User avatar
ahammel
My Little Cabbage
Posts: 2135
Joined: Mon Jan 30, 2012 12:46 am UTC
Location: Vancouver BC
Contact:

Re: Coding: Fleeting Thoughts

Postby ahammel » Sat May 02, 2015 11:35 pm UTC

The entire Internet is trying to sell me a logstash info pack all of the sudden.
He/Him/His/Alex
God damn these electric sex pants!

User avatar
ahammel
My Little Cabbage
Posts: 2135
Joined: Mon Jan 30, 2012 12:46 am UTC
Location: Vancouver BC
Contact:

Re: Coding: Fleeting Thoughts

Postby ahammel » Thu May 07, 2015 11:14 pm UTC

Is this a thing?

Code: Select all

class Monoid a => Thing a where
    (.*.) :: a -> a -> a
    -- mempty .*. _      = mempty
    -- _      .*. mempty = mempty
He/Him/His/Alex
God damn these electric sex pants!

User avatar
Xanthir
My HERO!!!
Posts: 5426
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Fri May 08, 2015 1:20 am UTC

This violates the monoid laws unless the type contains *only* the mempty value.
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

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

Re: Coding: Fleeting Thoughts

Postby chridd » Fri May 08, 2015 1:30 am UTC

Xanthir wrote:This violates the monoid laws unless the type contains *only* the mempty value.
I think that's a second (multiplication-like) operation in addition to (addition-like) mappend... like a ring but with fewer axioms.
~ chri d. d. /tʃɹɪ.di.di/ (Phonotactics, schmphonotactics) · she · Forum game scores
mittfh wrote:I wish this post was very quotable...

User avatar
Xanthir
My HERO!!!
Posts: 5426
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Fri May 08, 2015 6:06 am UTC

Ah, I see it! Yeah, it looks like approximately a, um, near-semiring? https://en.wikipedia.org/wiki/Near-semiring It satisfies axioms 1 and 4, appears to satisfy axiom 2, and maybe satisfies axiom 3; can't tell with the information we have here.
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

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

Re: Coding: Fleeting Thoughts

Postby raudorn » Fri May 08, 2015 5:12 pm UTC

STOP MAKING ME FEEL STUPID, PEOPLE!

*ahem* Maybe my being-jaded levels have just reached a new height being constantly surrounded by webdev, and the bad-to-mediocre kind at that. Maybe one day I can go find out what a monoid is and it won't be an exercise without any connection to the "programming" I do at work.

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

Re: Coding: Fleeting Thoughts

Postby Flumble » Fri May 08, 2015 9:52 pm UTC

raudorn wrote:*ahem* Maybe my being-jaded levels have just reached a new height being constantly surrounded by webdev, and the bad-to-mediocre kind at that. Maybe one day I can go find out what a monoid is and it won't be an exercise without any connection to the "programming" I do at work.

No worries, I'm also at a loss as to why you would use a monoid in programming, let alone extend it with an operation that turns the identity into an annihilating element.
By the way, you should send the webdevs to a long workshop on yesod. It's a first step towards seeing monoids in a program. :P

Maybe it's just a thinly disguised math question. Asking if there's a name for this structure by using haskell. In that case: well played, ahammel.

User avatar
ahammel
My Little Cabbage
Posts: 2135
Joined: Mon Jan 30, 2012 12:46 am UTC
Location: Vancouver BC
Contact:

Re: Coding: Fleeting Thoughts

Postby ahammel » Sat May 09, 2015 1:05 am UTC

Xanthir wrote:Ah, I see it! Yeah, it looks like approximately a, um, near-semiring? https://en.wikipedia.org/wiki/Near-semiring It satisfies axioms 1 and 4, appears to satisfy axiom 2, and maybe satisfies axiom 3; can't tell with the information we have here.
Yeah, some kind of hemidemisemiring was what I figured (my understanding of non-Haskell category theory is zilch). The context was some time-series data a colleague was working on that includes what was described as two kinds of null values, one of which means "don't add any data to the time series" and the other of which means "reset the entire time-series to null". That kind of reminded me of multiplication vs addition, but without a multiplicative identity. I can't think of a reasonable, associative way to multiply two non-null time series together though.

raudorn wrote:*ahem* Maybe my being-jaded levels have just reached a new height being constantly surrounded by webdev, and the bad-to-mediocre kind at that. Maybe one day I can go find out what a monoid is and it won't be an exercise without any connection to the "programming" I do at work.
A monoid is a combination of a function (which I will spell as the infix operator '<>') and a data structure with two properties:

1) There is an instance of the data structure (called mempty) such that `mempty <> a = a` and `a <> mempty = a`, where 'a' is any instance of the data structure.
2) '<>' is associative, i.e. `a <> ( b <> c ) = ( a <> b ) <> c`

For example: the integers form a monoid under addition, where '0' is the empty element (zero + a = a for all a, and a+(b+c) always equals (a+b)+c). List-like things usually form a monoid under concatenation where mempty is the empty list ([] ++ alist = alist, and a++(b++c) = (a++b)++c.

Flumble wrote:No worries, I'm also at a loss as to why you would use a monoid in programming, let alone extend it with an operation that turns the identity into an annihilating element.
I can think of at least two practical uses:

1) Abstracting concatenation. There are approximately eleventy billion different implementations of strings in Haskell, and I find annoying to have to worry about which kind I'm working with just to stick them together.
2) Joining a bunch of data with the monoid operation parallelizes for free.

Flumble wrote:Maybe it's just a thinly disguised math question. Asking if there's a name for this structure by using haskell. In that case: well played, ahammel.
Nah, practical(ish) Haskell question. I can barely math.
He/Him/His/Alex
God damn these electric sex pants!

User avatar
Xanthir
My HERO!!!
Posts: 5426
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Sat May 09, 2015 3:27 am UTC

Because I find Haskell's use of category theory terms to be obtuse and infuriating, I prefer calling this "Joinable". A class is joinable if you can join two instances together and get a third instance. Additionally, there has to be some "zero" instance, which you can join with anything without changing it, just like 0 in addition, 1 in multiplication, or the empty string in string concatenation.

So yeah, the good thing about monoids/joinables is that you know how to combine them together without having to care about the specific shape of the class (assuming your language has some sort of "typeclasses" that your class can opt into to say "I'm a Joinable, and here's my Join method"). This gives you a free "sum" operation that lets you, say, combine an array full of class instances into one (surprisingly useful!). It also lets you do all sorts of "build up a result in pieces" capabilities; for example, you can have something that walks a tree and lets you "log" some information at each node, returning the result at the end. You can do this with strings and just combine them as you go, of course, but if you define it with just the joinable typeclass, you can use *anything* - use Integers+Sum to get a count, or more complicated logging classes. (For example, Haskell automatically makes tuples of joinables be joinable, too, so if you want to keep a count *and* a log, just return a tuple of your log message and your addition to the count; it'll automatically combine with the stuff you returned previously.)

All the buzzwordy Haskell stuff is useful like this. "Functor" is a stupid name; it's just a class with a .map() method, so I call it "Mappable". It just means that the class instances hold some "internal" value, and you can run a function over it to get a new instance with the result. And here's the big secret - Monad is basically the same thing. It's means your class is Mappable, and if your function returns another instance of your class (rather than an instance of whatever the internal value was), there's some way to "smush" the two class instances together. This avoids you having a bunch of nested instances to deal with; you only ever have one wrapper instance around the "internal" value. There are a bunch of reasons why this is especially useful, which I won't get into here.
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 10 guests