Language:
switch to room list switch to menu My folders
Go to page: First ... 50 51 52 53 [54] 55 56 57 58 ... Last
[#] Wed Mar 10 2010 22:59:35 EST from Ford II @ Uncensored

[Reply] [ReplyQuoted] [Headers] [Print]

One of the motivators for Ford's (badly written) problem could be

Are you talking about the way I explained the problem or how the program was written such that I ended up with 7 parallel arrays to be gin with?

[#] Thu Mar 11 2010 09:29:42 EST from LoanShark @ Uncensored

[Reply] [ReplyQuoted] [Headers] [Print]



The latter.

[#] Thu Mar 11 2010 12:00:25 EST from Peter Pulse @ Uncensored

[Reply] [ReplyQuoted] [Headers] [Print]

The idea of total "generic programming" as a central feature of a language is interesting, I'd like to try it some time. But in almost all the languages in common use, it is possible to apply it as a general principle in the areas where it is most advantageous to apply it, you just have to WANT to make the effort, and if you have been at it a while, you know that it is going to save you trouble later, so you do it. You might not have type safety, you might not be able to use all your operators with no thought to type... But even in C, you can create a reuseable collection "class" that is able to store various data types, you can even, with a little cleverness, store different data types in the same collection. It's all a matter of wanting it. A more run-timey language is better because the language might maintain some information about each piece of data so that you don't have to maintain it yourself. In any case, I still think it is a joke to say that Java is not a good language for generic programming.. the unspoken but obvious comparison being made to C++. My experience with operator overloading in C++ is that it is a horrendous feature that causes far more errors than it prevents, and saves NO time in software development. Templates are also a hack. When I first started using C++, it didn't have templates.. so a lot of the "generic" stuff I was used to doing in C and Objective C was not possible, I had to revert to C in my C++ programs for that stuff, so that I could use looser typing. When templates finally came along, they kinda sucked but I used them.
I didn't like the way I had to migrate more and more of my code into the headers as I used my template types in more places. Eventually I had whole, complex classes totally implemented in the headers. That sucks.
At least Java came out of the gate with the ability to jam any object I cared to create onto a list without all that nonsense.

[#] Thu Mar 11 2010 12:11:30 EST from Spell Binder @ Uncensored

[Reply] [ReplyQuoted] [Headers] [Print]

Re: Haskell syntax.

I agree. Reading through the code examples in "Real World Haskell" usually forces me to do a double-take, do some googling, and reread previous sections in the book to figure out what's going on. I'm certinaly not an expert on the language, but I
can try to address what I can.

There definitely is an emphasis on keeping the syntax as uncluttered as possible. Function names and their parameters are separated by spaces, as are individual parameters, as opposed to grouping parameters inside parentheses and separating them
with commas. Probably the most important aspect of Haskell is that all functions are "curried." Meaning that, when you get down to it, all functions take only one parameter and return only one value. This took me a while to wrap my head around,
but it allows some very elegant programming techniques such as partial function application and
sections, which are features that, IMHO, contribute to generic programming.

Haskell does have type declarations for functions, but, as far as I know, they're not required. It works as long as the compiler can deduce (by inference) what the parameter types are from the function definition. Obviously, though, it's still
good practice to provide type declarations. The other thing is that Haskell's type declarations aren't inline with the function definition like Java, C, or C++. For example:

sum :: Int -> Int -> Int
sum a b = a + b

Declares sum as a function that takes two parameters, each of type Int, and returns a value of type Int.

I'm not sure what you're referring to about the "sparse switch statements" but there are two aspects that I think match what you're talking about. The first is pattern matching. Haskell allows the programmer to have multiple definitions
of a function, but, each definition has to have a parameter pattern. When the function is called, the Haskell compiler chooses a definition based on how the paremeters that the function is called with match the parameter patterns. As another
example:

sumList :: [Int] -> Int
sumList (x:xs) = x + sumList xs
sumList [] = 0

Here, ":" is the list construction operator. "1 : 2" creates the list "[1,2]",
"1 : [2,3]" creates the list "[1,2,3]", "1 : []" creates the list "[1]" since
"[]" is the empty list. Likewise, any list, "[a,b,c...z]" can be written in
terms of the list constructor: "a : b : c : ... : z : []" Thus, if sumList is
called with any list that has more than element, that list devolves into a
single element x, and the rest of the list, xs. This matches the pattern in the
first definition. Since sumList takes a list of Int's, the only other possible

valid pattern is an empty list. In that case, the second definition gets used.
If you forget to cover all the possible patterns when you define a function,
you'll get an error (at compile time) when you call the function.

The other language feature that mimics a switch statement is the guard.
Similar to pattern matching, it's used to select a definition to use. Unlike
pattern matching, though, a guard is a boolean expression that gets evaluated to
decide what to match. For example:

sumWholeNumbers :: [Int] -> Int
sumWholeNumbers (x:xs) | x >= 0 = x + sumWholeNumbers xs
| x < 0 = error "Only whole numbers allowed"
sumWholeNumbers [] = 0

I'm not completely sure what would happen if more than one guard expression
evaluated true, but I'd imagine the compiler would throw an error.

I haven't read up on monads, yet, so I can't really
say much about them.

I'd be glad to explain whatever I can, if anyone wants to know more. Or, if
you're really interested, I'd definitely recommend "Real World Haskell." You
can read it online at:

http://book.realworldhaskell.org/read/index.html
Haskell Binder

[#] Thu Mar 11 2010 17:43:41 EST from LoanShark @ Uncensored

[Reply] [ReplyQuoted] [Headers] [Print]

Mar 11 2010 12:00pm from Peter Pulse @uncnsrd
The idea of total "generic programming" as a central feature of a
language is interesting, I'd like to try it some time. But in almost


(scheme) is the best example of this. Ford stated that templates are really just fancy macro expansions. In C++, that's true. In Java, generics are just a fancy extension to the type checking system, and all they do it save you a little typing via type inference. So you don't have to cast everything.

Scheme macros are way more powerful, from what I understand - you can extend the compiler with arbitrarily flexible new grammar for your specific purpose. Templates on steroids. But they come with all those darn (parentheses.)

[#] Thu Mar 11 2010 17:53:45 EST from LoanShark @ Uncensored

[Reply] [ReplyQuoted] [Headers] [Print]

Haskell Binder

Your name is an embedded pun, unbeknownst to you. "bind" is one of the two primitives that define a monad. (Haven't I also seen partial application of a curried function referred to as "bind"ing?)

[#] Thu Mar 11 2010 17:57:49 EST from LoanShark @ Uncensored

[Reply] [ReplyQuoted] [Headers] [Print]

I'm not sure what you're referring to about the "sparse switch statements"
but there are two aspects that I think match what y
Yes, it's the obvious translation of typical mathematical notation to define a function that has cases, and it's somewhat surprising that no other computer language (that I can think of) has done this.

The canonical Haskell factorial:

fac :: Integer -> Integer
fac 0 = 1
fac n | n > 0 = n * fac (n-1)

Seems to have an unspecified runtime edge case where n < 0.

[#] Thu Mar 11 2010 18:04:50 EST from LoanShark @ Uncensored

[Reply] [ReplyQuoted] [Headers] [Print]


and an alternative Haskell factorial:

fac = product . enumFromTo 1

While it makes clever use of currying, is far too sparse for most programmers who haven't thoroughly drained the punchbowl.

[#] Thu Mar 11 2010 21:01:02 EST from LoanShark @ Uncensored

[Reply] [ReplyQuoted] [Headers] [Print]

fac = product . enumFromTo 1

See now here's a shining example of how Java is at least as, umm, adequate, as C++. (Damning with faint praise here. :)

The above fascinated me so much that I had to translate it to Java. 1 line of Haskell = 91 idiomatic lines of Java. Now that wasn't so hard, eh? I'm
sure the C++ would be equally awful.

import java.util.Iterator;

public final class Haskell {

public static void main(String[] argv) {
System.out.println("2! = " + factorial.of(2));
System.out.println("3! = " + factorial.of(3));
}

private Haskell() {
}

private interface Function<T, U> {
T of(U arg);
}

private static final class ComposedFunction<T, U, V> implements
Function<T, V> {
private final Function<T, U> func1;
private final Function<U, V> func2;

private ComposedFunction(Function<T, U> func1, Function<U, V> func2) {
this.func1 = func1;
this.func2 = func2;
}

public
T of(V arg) {
return func1.of(func2.of(arg));
}
}

private static final class IntegerIterator implements Iterator<Integer> {
private final Integer to;
private Integer currentValue;

private IntegerIterator(Integer to, Integer from) {
this.to = to;
currentValue = from;
}

public boolean hasNext() {
return currentValue <= to;
}

public Integer next() {
return currentValue++;
}

public void remove() {
throw new UnsupportedOperationException();
}
}

private static final class IntegerIterable implements Iterable<Integer> {
private final Integer to;
private final Integer from;

private IntegerIterable(Integer to, Integer from) {
this.to = to;
this.from = from;
}

public Iterator<Integer> iterator() {
return new IntegerIterator(to, from);
}
}

private static final class IterateFromTo implements
Function<Iterable<Integer>, Integer>
{
private final Integer from;

private IterateFromTo(Integer from) {
this.from = from;
}

public Iterable<Integer> of(final Integer to) {
return new IntegerIterable(to, from);
}
}

private static final Function<Integer, Iterable<Integer>> product = new Function<Integer, Iterable<Integer>>() {
public Integer of(Iterable<Integer> arg) {
int rval = 1;
for (Integer i : arg) {
rval *= i;
}
return rval;
}
};

private static final Function<Integer, Integer> factorial = new ComposedFunction<Integer, Iterable<Integer>, Integer>(
product, new IterateFromTo(1));
}

[#] Fri Mar 12 2010 10:59:05 EST from Spell Binder @ Uncensored

[Reply] [ReplyQuoted] [Headers] [Print]

The canonical Haskell factorial:

fac :: Integer -> Integer
fac 0 = 1
fac n | n > 0 = n * fac (n-1)

Seems to have an unspecified runtime edge case where n < 0.


Yes, indeed it does. A more complete and error-free implementation could be something like this:

fact :: Integer -> Maybe Integer
fact 0 = Just 1
fact n | n > 0 = Just $ n * fact (n - 1)
| n <= 0 = Nothing

The "Maybe" parameterized type is similar to handling values in a database.
A field in a record can have a value, "Just x", or be NULL, "Nothing".
Just Binder

[#] Fri Mar 12 2010 11:04:14 EST from Spell Binder @ Uncensored

[Reply] [ReplyQuoted] [Headers] [Print]

Mar 11 2010 6:04pm from LoanShark @uncnsrd

and an alternative Haskell factorial:

fac = product . enumFromTo 1

While it makes clever use of currying, is far too sparse for most
programmers who haven't thoroughly drained the punchbowl.


Currying and partial function application (when it gets evaluated). When I came across this, this was what immediately made me think of generic programming, because that kind of code makes you focus more on what the code actually means than worrying about syntactic distractions.
Curry Binder

[#] Fri Mar 12 2010 11:18:38 EST from Spell Binder @ Uncensored

[Reply] [ReplyQuoted] [Headers] [Print]

As to implementing Haskell constructs in other languages, I was experimenting with some of that with TCL, and the results, especially when trying to implement currying correctly, are just as verbose. However, if you don't mind cheating, here's a poor man's implementation.

proc . {f g args} {
return [$f [$g $args]];
}

proc enumFromTo {from to} {
set lst [list];
for {set i $from} {$i <= $to} {incr i} {
lappend lst $i;
}
return $lst;
}

proc product {lst} {
set prod 1;
foreach num $lst {
set prod [expr $prod * $num];
}
return $prod;
}

proc factorial {num} {
return [. product enumFromTo $num];
}

Obviously, there's no real currying going on here, and the function composition "operator", "." is strictly evaluating the functions passed into it, as opposed to forming a new function as it would in Haskell. Also, since TCL is an untyped language (everything's a string), these procedures will all blow up very nicely if passed the wrong data.
TCL Binder

[#] Fri Mar 12 2010 11:41:03 EST from Spell Binder @ Uncensored

[Reply] [ReplyQuoted] [Headers] [Print]

The other thing to remember with your Haskell example of factorial is that you're using a lot of pre-built library functions. Writing that from scratch would be a bit more verbose.

(.) :: (a -> b) -> (b -> c) -> (a -> c)
f . g = f g

enumFromTo :: Enum a => a -> a -> [a]
enumFromTo from to | from < to = from : enumFromTo (from + 1) to
| from > to = from : enumFromTo (from - 1) to
| otherwise = from : []

product :: Num a => [a] -> a
product (x:xs) = x * product xs
product [] = 1

myFactorial :: Enum a => a -> a
myFactorial = product . enumFromTo 1

Which, if I've coded everything correctly (I don't have a Haskell compiler handy to verify everything), would work without the Prelude (Haskell's version of the standard C library). It's still more compact than either your Java implementation or my TCL implementation.
Spell

[#] Fri Mar 12 2010 12:13:54 EST from LoanShark @ Uncensored

[Reply] [ReplyQuoted] [Headers] [Print]

proc enumFromTo {from to} {
set lst [list];
for {set i $from} {$i <= $to} {incr i} {
lappend lst $i;
}
return $lst;
}

The trick when doing crap like this is to return an efficient list implementation that doesn't consume memory - you don't need it to, because you're only iterating over it, and the contents of the list can be generated by an Iterator. The problem with functional languages that can easily iterate binary functions over a list in 1 line of code - they encourage using lists everywhere, and who knows whether the compiler is really optimizing that.

[#] Fri Mar 12 2010 13:27:18 EST from Spell Binder @ Uncensored

[Reply] [ReplyQuoted] [Headers] [Print]

I can definitely see your point about iterators vs. list building. That's somethign I need to look into more closely. One of the pieces of our automated test system is showing signs of a slow memory leak. It's written in TCL, and the TCL interpreter, from what I've read, will allocate memory for TCL objects, but rarely, if ever, gives it back. If I can identify places in our code where we could use an iterator instead of building a list, it might help reduce memory usage and plug the leak.

I'll have to try rewriting that TCL factorial using an iterator to get some practice.
Leaky Binder

[#] Fri Mar 12 2010 15:52:59 EST from dothebart @ Uncensored

[Reply] [ReplyQuoted] [Headers] [Print]

and now we'd like to have some facts about resource useage.

if you do it 100 times, which takes how much? cpu time? user time? ram?

as... In the end a cute syntax but performance to turn an uber xeon into a pocket calculator, its not of much use ;)



[#] Sun Mar 14 2010 20:56:34 EDT from Ford II @ Uncensored

[Reply] [ReplyQuoted] [Headers] [Print]

generics are just a fancy extension to the type checking system, and
all they do it save you a little typing via type inference. So you
don't have to cast everything.

heh, yeah, it makes the code cleaner, but it doesn't save you any typing, because eclipse types in all the casts for you anywy... :-)

[#] Sun Mar 14 2010 21:02:19 EDT from Ford II @ Uncensored

[Reply] [ReplyQuoted] [Headers] [Print]

I think your 91 line implementation is a little.... flowery.
I'm sure there's a few lines of java that wouldn't translate well in haskell.
The question is, are you translating the language or accomplishing the goal. You were translating the language, and while you've made your point, that's not even how you port software so it's a bit of an acedemic argument.

[#] Sun Mar 14 2010 22:29:35 EDT from LoanShark @ Uncensored

[Reply] [ReplyQuoted] [Headers] [Print]


I may have embellished a little, but not much ;)

[#] Mon Mar 15 2010 21:31:12 EDT from LoanShark @ Uncensored

[Reply] [ReplyQuoted] [Headers] [Print]

Nice thing about Java generics is that it enables novel type constraints. Having this declared this way caught one of my mistakes today:

public <T extends HasPrimaryKey<U>, U extends Serializable> T getEntity(
Class<T> klass, U primaryKey) {
Session session;

session = HibernateUtil.currentSession();
return (T) session.get(klass, primaryKey);
}

Go to page: First ... 50 51 52 53 [54] 55 56 57 58 ... Last