Open Side Menu Go to the Top

03-14-2013 , 11:36 PM
Quote:
Originally Posted by tyler_cracker
dave,

i think there's something wrong with your repl; it got sed all over my nice functional side-effectless program!
Hmmm... Maybe. Let me run that in an actual program then:

Code:
(defn -main []
  (eval '(lol wp)))
Code:
=> lein run
Exception in thread "main" java.lang.RuntimeException: Unable to resolve symbol:
 lol in this context, compiling:(NO_SOURCE_PATH:27)
        at clojure.lang.Compiler.analyze(Compiler.java:6235)
        at clojure.lang.Compiler.analyze(Compiler.java:6177)
        at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3452)
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:6411)
        at clojure.lang.Compiler.analyze(Compiler.java:6216)
        at clojure.lang.Compiler.analyze(Compiler.java:6177)
        at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5572)
        at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5008)
        at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3629)
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:6407)
        at clojure.lang.Compiler.analyze(Compiler.java:6216)
        at clojure.lang.Compiler.eval(Compiler.java:6462)
        at clojure.lang.Compiler.eval(Compiler.java:6431)
        at clojure.core$eval.invoke(core.clj:2795)
        at compojure.core$_main.invoke(core.clj:27)
        at clojure.lang.Var.invoke(Var.java:397)
        at user$eval36.invoke(NO_SOURCE_FILE:1)
        at clojure.lang.Compiler.eval(Compiler.java:6465)
        at clojure.lang.Compiler.eval(Compiler.java:6455)
        at clojure.lang.Compiler.eval(Compiler.java:6431)
        at clojure.core$eval.invoke(core.clj:2795)
        at clojure.main$eval_opt.invoke(main.clj:296)
        at clojure.main$initialize.invoke(main.clj:315)
        at clojure.main$null_opt.invoke(main.clj:348)
        at clojure.main$main.doInvoke(main.clj:426)
        at clojure.lang.RestFn.invoke(RestFn.java:421)
        at clojure.lang.Var.invoke(Var.java:405)
        at clojure.lang.AFn.applyToHelper(AFn.java:163)
        at clojure.lang.Var.applyTo(Var.java:518)
        at clojure.main.main(main.java:37)
Caused by: java.lang.RuntimeException: Unable to resolve symbol: lol in this con
text
        at clojure.lang.Util.runtimeException(Util.java:156)
        at clojure.lang.Compiler.resolveIn(Compiler.java:6720)
        at clojure.lang.Compiler.resolve(Compiler.java:6664)
        at clojure.lang.Compiler.analyzeSymbol(Compiler.java:6625)
        at clojure.lang.Compiler.analyze(Compiler.java:6198)
        ... 29 more
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **
$25m Guaranteed WPM on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **
03-14-2013 , 11:51 PM
Quote:
Originally Posted by Xhad
Speaking of Python wat, here is something I just discovered today:

Code:
# assume L is a list both times

def f1(L):
    L += [1]

def f2(L):
    L = L + [1]
They don't do the same thing. Even Guido thinks this is horrible.
I just ran that. Absolutely speechless. You have to put in a return statement to get the full effect.

Quote:
Re: the mutable defaults thing, I've been using Python for awhile and I've actually been bitten by that bug zero times, and written code that depended on that behavior, but I'm inclined to agree with Neil in principle and regard it as "probably a necessary evil." I don't really know how you would fix it without copy.deepcopying the defaults dict every time the function is called, especially when you consider the possibility of nested mutable structures.
I've been bitten by Python list bugs quite a bit. I think today's lesson is quite valuable in isolating some of it, though. I think your newest example will also help.

I always pull through the bugs and consider them more or less minor irritants, but I could never keep track of when and where they happen.

Quote:
daveT: I don't understand why it follows that hates FP = hates python lists. Wouldn't FP types like tuples better anyway since they have essentially every property of lists except side effects?
I was being snarky, but who the hell likes tuples? Regardless, Python Lists are much closer to C-style arrays than Lisp Lists. Totally different perspectives.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-14-2013 , 11:55 PM
tuples are immutable, so they're handy for a variety of things.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 12:05 AM
Humorously enough, this default argument discussion is actually a good example since tuples generally behave as you would expect them to there (anything that would behave strangely with a list default would throw an exception if it were a tuple). I've also made use of them as dictionary keys in the past.

FWIW, another thing that strikes me as odd about this whole discussion: I feel like if Python fans are going to praise the fact that this is an exception:

Code:
if x = 1:
#blah
Then it seems hypocritical to me not to be bothered by the mutable defaults thing. It seems like it breeds bugs for, like, the exact same reason and at least should be a warning if it isn't already.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 12:44 AM
I suppose tuples would be better for default arguments, except that you have to have this in some places:

Code:
### mutate
a = list(a) 

### Okay, done mutating or doing things that require me to use a list, 

### return a Tuple now!
a = tuple(a)

The whole thing about mutation is a little over-blown. I honestly don't see what the big deal about it is, but Immutable Thing != FP Thing. In some essence, it does, but suppose that you could do a list comprehension and shove out a tuple instead of a generator?

squares = tuple(x**2 for x in range(10))

It feels pretty unpythonic and hackish to do that. Python, as far as I know, isn't envisioned to be a function, multi-threaded, concurrent programming language. It does what it does very well and I'm cool with that. No one is suggesting adding pointers and bit-movers to the language.

***

What is the issue with the x = 1 program? A comparator should be == and that's fine by me unless I'm missing something.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 12:54 AM
Re: the if thing, it has to do with the fact that this is a common construct in some languages like C:

Code:
while (line = get_line(file)):
    do_stuff_to(line)
Python intentionally doesn't let you do that, to protect you from this common bug:

Code:
if (status = under_attack):
    launch_nuclear_missles()
The mutable default thing seems similar to me, in that if someone hasn't been explicitly informed of it, I'd think it's more likely to be a bug than someone intentionally making use of that behavior. I have trouble seeing how someone can love the if decision but not at least be slightly bothered by the mutable defaults pitfall.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 01:30 AM
I'm not understanding. You'll have to step me through this like I'm a 5 year old.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 01:34 AM
maybe he means the 'common bug' is the = instead of == ?
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 01:47 AM
Quote:
Originally Posted by greg nice
maybe he means the 'common bug' is the = instead of == ?
Yes, this. It's a classic bug in C-like languages. It's easy to write:

Code:
if (x=1) // This code always runs!
when you mean:

Code:
if (x==1) // This code only runs when x is 1
Python assumes you wanted the second one and makes the first one a SyntaxError. If you wanted the first one, the official answer is "do something else". (in the while loop from my earlier post, it's assumed that the file reading function returns some boolean false value when there are no more lines to read)
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 01:49 AM
some languages use := for assignment and = for comparison, then the bug is a non issue

Code:
while (line := get_line(file))
    do_stuff_to(line)
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 02:28 AM
Quote:
Code:
print('2^' + str(i) + '=' + str(n[-1]))
Surely you mean
Code:
print('2^' + str(i) + '=' + str(n[i]))
?

Quote:
Guido is not a fan of Lisp, not a fun of functional programming, thus I suspect he's not a fan of the list data type, which is why it sometimes feels like a huge middle finger when you get too fancy with lists in Python.
I think lists are pretty good in Python. Not really missing anything. Prolog style [Head|Tail] is l[:1] + l[1:] in Python etc.
l[::2] is kind of nice as well etc.

I mean I guess ['a','b'|Tail] type declarative stuff would be nice but you can probably use l[:2] == ['a','b'] and tail=l[2:] or something (lowercase variable name since we're not in Prolog-land)
Code:
tail = l[2:] if l[:2] == ['a','b'] else []
or smth., can replace the ['a','b'] with a matching variable and the 2 with len(['a','b']) or len(datvariableson)

Last edited by clowntable; 03-15-2013 at 02:50 AM.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 02:59 AM
I meant exactly what I wrote. It was joke program and that was the critical point: you'd expect n to create a new stream object and pop off the last item as the correct answer but that didn't happen.

Xhad: I have no real thoughts on that particular issue. C and Python handle Booleans okay for my tastes.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 03:19 AM
Oh lol I get it now, too early.
*gets coffee*

Quote:
some languages use := for assignment and = for comparison, then the bug is a non issue
The problem is that if you switch from that language to a C-family language you'll assume = means comparison and launch them missiles.

If I were to design a new language I'd actually use := for assignment and == for comparison and leave = to rot. Then it would never get used because people would complain about it looking ugly and/or having to type an extra character

Last edited by clowntable; 03-15-2013 at 03:29 AM.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 03:36 AM
Quote:
Originally Posted by tyler_cracker
i was in a meeting today at work about our mail systems. one of the reports we looked at showed delivery failures. mostly it was stuff like hotmai.com and verion.com -- places where people typo'd while trying to enter an address. my boss was interested in the top entry:

boss: "what's homail.com?"
me: "it's where your mom checks her email."
So how much is the severence check?
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 04:18 AM
Quote:
Originally Posted by Xhad
Re: the if thing, it has to do with the fact that this is a common construct in some languages like C:

Code:
while (line = get_line(file)):
    do_stuff_to(line)
Python intentionally doesn't let you do that, to protect you from this common bug:

Code:
if (status = under_attack):
    launch_nuclear_missles()
The mutable default thing seems similar to me, in that if someone hasn't been explicitly informed of it, I'd think it's more likely to be a bug than someone intentionally making use of that behavior. I have trouble seeing how someone can love the if decision but not at least be slightly bothered by the mutable defaults pitfall.
Python has the "for line in file:" construct which IMO is clearer than "while(line=get_line(file))"
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 07:25 AM
Quote:
Originally Posted by Xhad
Re: the mutable defaults thing, I've been using Python for awhile and I've actually been bitten by that bug zero times, and written code that depended on that behavior, but I'm inclined to agree with Neil in principle and regard it as "probably a necessary evil." I don't really know how you would fix it without copy.deepcopying the defaults dict every time the function is called, especially when you consider the possibility of nested mutable structures.
I'd argue your code depending on that 'feature' was bad. Obviously I don't know for sure, but it seems pretty likely to me.


Quote:
Originally Posted by Xhad
Re: why the other way could ever be a gotcha, here's an example stolen from the SO post:

Code:
bread = (1,2,3)

def toast(food = bread):
    # do things

# bunch of other code

bread = (8, 6, 7, 5, 3, 0, 9)

# a lot of other code

toast()
I think either of these would be better:

1. Deepcopy the object like you said. Slow performance is better than a really unintuitive bug.

2. If a reference to an existing object is used as the default then leave the behaviour as it is. If you're instantiating a new object than that should be done every single time.

From a user centric point of view I can't think of any good reason at all that what Neil said wouldn't hold:

Quote:
Just seems to me that invoking a function with a default argument of [1,2,3] passed with no arguments, should behave the same as if I invoke with an argument of [1,2,3]
and I think both 1 and 2 achieve that.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 09:18 AM
The more I think about it my #2 above seems like the obvious right answer to this.

If you specify a default parameter as a reference to an existing object it seems intuitive that you'll get that same reference every time. If your default parameters is constructing a new object it seems intuitive that its built every time.

It gives you the semantics you expect when calling the method since if you copied the text from the default parameter into the appropriate place when calling the function you'd get exactly the same behaviour.

It also has no real performance penalties. Yes building an object on every invocation could be expensive but its intuitive that if you're calling a function with an expensive-to-create object as a default parameter its going to be expensive to call it many times and force that creation every time.

My compiler skills are limited and rusty but it seems like it should be easy to differentiate between an existing symbol and code that creates a new object. Who knows, but I could accept a "this solution was too hard" much better than trying to pretend what they're doing now is the best design.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 11:30 AM
Quote:
Originally Posted by jjshabado
2. If a reference to an existing object is used as the default then leave the behaviour as it is. If you're instantiating a new object than that should be done every single time.
Strictly interpreting this, this is almost unimplementable. What if you have a function call?

I think what you meant to say is simply evaluate the expression in the function definition scope at function invocation. Essentially wrap the expression being passed in a lambda. I think this is how it works in most languages (just confirmed with Scala and C++).

Edit: Another way of saying this is simply push the evaluation of the expression into the body of the function.

Last edited by candybar; 03-15-2013 at 11:35 AM.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 11:39 AM
Quote:
Originally Posted by daveT
I was being snarky, but who the hell likes tuples? Regardless, Python Lists are much closer to C-style arrays than Lisp Lists. Totally different perspectives.
What's worse, what they call "tuple" in Python is a "list" in functional languages. A real "tuple" in a functional language is generally distinguished from a list by the fact that an n-tuple does not have the same static type as an (n+1) tuple.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 01:04 PM
Only when talking to developers do you have someone say:

"Strictly what you're saying is completely wrong. But I understand what you actually mean and thats the way it works most of the time."

Last edited by jjshabado; 03-15-2013 at 01:04 PM. Reason: Maybe lawyers? But we all know how much people like talking to lawyers...
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 01:15 PM
*nerdalarm*
Marvel announced that they'd release 700 free digital #1 issues which lead to their webshop being down for iirc 2 days. You still can't get them due to technical problems that's 5 days now iirc...WTF kind of "technical partner" do they have that lets this happen.

It's tilting I want free comic books :P
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 02:26 PM
Anyone have any thoughts here? I'm currently fairly well connected in the Philly area Tech scene and getting more networked every month. I work full time and have a mortgage and wife so more than 2 classes at a time is out of the question. All pre-reqs are completed.

Goals:
1 - get a job in tech (no specific area) because I hate my job.
2 - eventually get degree as a software engineer.
3 - VERY LONG TERM (start a company/ join a startup)

So I need to decide between two paths.

Path 1. Programming Associates degree, probably gets me a job ~ 1 year.

http://www.dccc.edu/programs-study/c...rogramming-aas

Path 2. Mobile computing.
Essentially an App building and website building degree. Prob gets me employed in shorter time span (sept). Won't be as helpful for eventual software engineering degree but will get me real life experience.

http://www.dccc.edu/programs-study/c...-computing-aas
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 02:49 PM
yeah.. it seems pretty reasonable to me that the code
Code:
def func(param=x) :
  #whatever
should be equivalent to

Code:
def func(param) :
  if param.not_assigned() : #I made this up!
    param = x
  
  #whatever
Smarter people than I have thought about this longer than I have, so I'm probably missing some reason that that sucks, though.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 02:54 PM
Oh.. I guess side effects could be a really annoying problem with that. E.g. the default parameter could evaluate some function with side effects.

I'm glad I don't design languages.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-15-2013 , 03:12 PM
Noah, I think your post is still correct.

Even if evaluating x causes a side effect I think the intuitive assumption is that the side effect occurs every time you execute that function without a value for param.

For example:

Code:
class A:
    def __init__(self):
         update_some_database_field()

def foo(o=A()):
    do_stuff()
Even though constructing A has a side effect it seems reasonable that it would occur every time you call foo.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **
$25m Guaranteed WPM on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **

      
m