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

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

>>=
There are three exponentiation operators:
- (^) raises a number to a non-negative integer power (and is defined in terms of multiplication).
- (^^) raises a float to an integer power.
- (**) raises a float to a float power.

And by 'float' here I mean an instance of the Fractional typeclass which could be float, double, ratio, etc etc and by 'integer' I mean any instance of the Integral typeclass which includes int, integer, uints (called Word in haskell), etc.

edit: The best way to have diagnosed this on your own is to search hoogle for (^). Then you see that (^)'s second argument requires a member of Integral. What's that you ask? Just click on it to see its definition, what methods it defines, and a list of instances (crucially, which float is not in). Although from then I guess you're stuck unless you start searching through the docs for the other exponentiation functions.

gonadic io fucked around with this message at 08:48 on Jun 21, 2015

Adbot
ADBOT LOVES YOU

Dominoes
Sep 20, 2007

Thank you. That explanation makes sense, and my code works now.

sarehu
Apr 20, 2007

(call/cc call/cc)

gonadic io posted:

- (^^) raises a float to an integer power.

Huh. It's a shame that they reappropriated the logical xor operator for this.

gonadic io
Feb 16, 2011

>>=
The bit operators are .|., .&., xor, compliment, shift, rotate, and more.

The logical operators are &&, ||, and not.

Not ideal I guess but it's not exactly a language designed for bit-janitoring.

Dominoes
Sep 20, 2007

lol

Xi over Xi-bar
May 10, 2009
You can always use /= for logical xor.

gonadic io
Feb 16, 2011

>>=
Also Boolean is a valid instance for Bits so you can do all the logical operators to it. Even if things like shift won't make a lot of sense.

sarehu
Apr 20, 2007

(call/cc call/cc)
Yeah but those aren't short-circuiting.

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?

sarehu posted:

Yeah but those aren't short-circuiting.

You can't short-circuit xor anyway

gonadic io
Feb 16, 2011

>>=
Also given that Data.Bits.(.&.) and (.|.) for Bools are defined as (&&) and (||) respectively they will short circuit.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

gonadic io posted:

(.|.) for Bools

I read that 3 times over wondering why Haskell had a Boobs operator.

gonadic io
Feb 16, 2011

>>=

Bognar posted:

I read that 3 times over wondering why Haskell had a Boobs operator.

(.).(.) is real, and occasionally useful.

QuantumNinja
Mar 8, 2013

Trust me.
I pretend to be a ninja.

gonadic io posted:

(.).(.) is real, and occasionally useful.

Ah, yes, the Total Recall composition operation.

VikingofRock
Aug 24, 2008




gonadic io posted:

(.).(.) is real, and occasionally useful.

I had never seen that operator before, but after sitting down with a pen and paper and figuring out what it does, that's really useful! I'll have to remember that.

gonadic io
Feb 16, 2011

>>=

VikingofRock posted:

I had never seen that operator before, but after sitting down with a pen and paper and figuring out what it does, that's really useful! I'll have to remember that.

It usually gets named (.:). Honestly I don't use it so much now, as I'm trying to cut back a little on how pointfree my code is.

P.S.: it can also be defined, a little more generally, as 'fmap fmap fmap'.

VikingofRock
Aug 24, 2008




gonadic io posted:

I'm trying to cut back a little on how pointfree my code is.

Is this mostly out of readability concerns?

Another question I've been pondering: does pointfree style affect performance through memoization? This article seems to indicate that it does, but I'm not sure I fully understand what it's saying.

fart simpson
Jul 2, 2005

DEATH TO AMERICA
:xickos:

VikingofRock posted:

I had never seen that operator before, but after sitting down with a pen and paper and figuring out what it does, that's really useful! I'll have to remember that.

You're the problem.

VikingofRock
Aug 24, 2008




fart simpson posted:

You're the problem.

Guilty as charged.

gonadic io
Feb 16, 2011

>>=

VikingofRock posted:

Is this mostly out of readability concerns?

Yes. It's not worth obscuring the code just to save 3-4 characters. I mean at one point I was using (.::), (.:::) etc and it was just impossible to work out what was going on.

VikingofRock posted:

Another question I've been pondering: does pointfree style affect performance through memoization? This article seems to indicate that it does, but I'm not sure I fully understand what it's saying.

Automatic momoization is extremly unintuitive and finicky in haskell. If you need something to memoise, either store it in an explicit list and pass it around, or you have to do the same kind of test as in that post. Or you could just use a library like memo that does it explicitly behind the scenes.

TopherCStone
Feb 27, 2013

I am very important and deserve your attention
F# is really cool. I'm working through F# For Fun and Profit right now and it seems pretty good. There are times when it references something I don't understand and it's not always clear whether they assume I already have the knowledge or if it's going to be discussed in more detail later, but overall I like it.

edit: like this example is really cool

code:
// set up the vocabulary
type DateScale = Hour | Hours | Day | Days | Week | Weeks
type DateDirection = Ago | Hence

// define a function that matches on the vocabulary
let getDate interval scale direction =
    let absHours = match scale with
                    | Hour | Hours -> 1 * interval
                    | Day | Days -> 24 * interval
                    | Week | Weeks -> 24 * 7 * interval
    let signedHours = match direction with 
                       | Ago -> -1 * absHours
                       | Hence -> absHours
    System.DateTime.Now.AddHours(float signedHours)

// test some examples
let example1 = getDate 5 Days Ago
let example2 = getDate 1 Hour Hence
That would be annoyingly verbose in C#

Here's the output:
code:
val example1 : System.DateTime = 6/22/2015 4:30:52 PM
val example2 : System.DateTime = 6/27/2015 5:30:52 PM

TopherCStone fucked around with this message at 21:34 on Jun 27, 2015

QuantumNinja
Mar 8, 2013

Trust me.
I pretend to be a ninja.
Question about Elm: how would I go about making an Elm application interact with a database backend? The 'easiest' way I can imagine from the API is to use JSON to post requests to some server-side script and get the results back. Is there an approach (maybe as a library or tutorial) that doesn't require doing something like that for user login authentication?

Arcsech
Aug 5, 2008

QuantumNinja posted:

Question about Elm: how would I go about making an Elm application interact with a database backend? The 'easiest' way I can imagine from the API is to use JSON to post requests to some server-side script and get the results back. Is there an approach (maybe as a library or tutorial) that doesn't require doing something like that for user login authentication?

Maybe the Firebase bindings? That's about all I know of.

fart simpson
Jul 2, 2005

DEATH TO AMERICA
:xickos:

QuantumNinja posted:

Question about Elm: how would I go about making an Elm application interact with a database backend? The 'easiest' way I can imagine from the API is to use JSON to post requests to some server-side script and get the results back. Is there an approach (maybe as a library or tutorial) that doesn't require doing something like that for user login authentication?

I'd probably look at the Firebase bindings linked above. Even if you don't use it, you can look at that for ideas on how you'd generally do something like this. This is really something that you'd want to implement with the relatively new Task system in Elm, but I think you could also do something with http or websockets to communicate with a backend. It might not be that hard to write bindings for an existing Javascript library that can do what you want, either.

There aren't really many libraries for something like this at this point.

Mathlete
Nov 30, 2005

It's hip to be a squared square.
I've been trying to teach myself Racket by making a few list-eaters and solving some of the beginning Project Euler challenges in it.

For the most part, I think the functional way of doing things is really neat, but there are occasional challenges that I don't see any clean approach to solving without falling back on the old standard of iterating over a mutable array.

The big example is implementing a prime number sieve. In python, I'd just make a bitstring or something and play whack-a-mole. It's true that you can always set! the elements of mutable vectors in Racket, but the process is so wordy that you are practically discouraged from doing it. What would you do in a language like Haskell where apparently you can't mutate anything?

Are functional programming languages just less ideal for the sorts of projects where you find yourself doing a lot of little updates?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

Mathlete posted:

The big example is implementing a prime number sieve. In python, I'd just make a bitstring or something and play whack-a-mole. It's true that you can always set! the elements of mutable vectors in Racket, but the process is so wordy that you are practically discouraged from doing it. What would you do in a language like Haskell where apparently you can't mutate anything?

Funny you should ask - there's a rather interesting paper around exactly this question, which also explains quite well why the "straightforward" functional implementation one might write is actually completely terrible.

Jabor fucked around with this message at 11:20 on Jul 20, 2015

MononcQc
May 29, 2007

This has been the major challenge of functional programming, IMO. Most of the algorithms you'll see out there that do any form of dynamic programming will use a mutable array somewhere in there, or will make assumptions of things like O(1) hashtables. In an immutable language, O(log n) with a high branching factor is as good as it gets without special runtime support to hide that poo poo, most of the time, or possibly amortized O(1), which still ends up having a high cost here and there.

Almost every time you want to use an algorithm you know, you end up having to find a clever way to transform it to work a bit differently (or to invent your own variation of it) so that it meshes well with the stuff supported by your language and its constraints.

raminasi
Jan 25, 2005

a last drink with no ice
Which is why it's real nice when your mostly-functional language also has concise facilities for iteration and mutation.

dougdrums
Feb 25, 2005
CLIENT REQUESTED ELECTRONIC FUNDING RECEIPT (FUNDS NOW)

MononcQc posted:

Almost every time you want to use an algorithm you know, you end up having to find a clever way to transform it to work a bit differently (or to invent your own variation of it) so that it meshes well with the stuff supported by your language and its constraints.

I did my dynamic programming homework in lisp today, because someone told me about an auto-memoization macro. It was the first time I've used lisp since I read a book about it like a decade ago.

Edit: Honestly the first thing that weirded me out about F# was immutability, but I understand what they're going for.

dougdrums fucked around with this message at 03:17 on Jul 21, 2015

QuantumNinja
Mar 8, 2013

Trust me.
I pretend to be a ninja.

MononcQc posted:

This has been the major challenge of functional programming, IMO. Most of the algorithms you'll see out there that do any form of dynamic programming will use a mutable array somewhere in there, or will make assumptions of things like O(1) hashtables. In an immutable language, O(log n) with a high branching factor is as good as it gets without special runtime support to hide that poo poo, most of the time, or possibly amortized O(1), which still ends up having a high cost here and there.

Almost every time you want to use an algorithm you know, you end up having to find a clever way to transform it to work a bit differently (or to invent your own variation of it) so that it meshes well with the stuff supported by your language and its constraints.

The upside, of course, is that the implementation will be 150 lines shorter! :boom:

:saddowns:

Mathlete
Nov 30, 2005

It's hip to be a squared square.

Jabor posted:

a rather interesting paper around exactly this question

Wow, that so directly addressed my question, it's kind of eerie. Thanks for sharing the link.

MononcQc posted:

Almost every time you want to use an algorithm you know, you end up having to find a clever way to transform it to work a bit differently (or to invent your own variation of it) so that it meshes well with the stuff supported by your language and its constraints.

The above paper gives a good illustration of this--of finding a clever way to transform the algorithm to fit the idiom of the language.

What is frustrating for a beginner is that we can only be counted on to come up with a handful of somewhat clever designs every week or so. It is easy to forget that the sieve of eratosthenes is already a superbly clever idea. If a beginner had the amazing flash of insight to come up with the sieve solution on his own, he would immediately be discouraged by the fact that it can't be implemented directly but it would take at least three more subtle and ingenious ideas to adapt it to a functional style.

Maybe this is just my attitude because I am still inexperienced, but I feel like with imperative programming you can implement a clever idea in an obvious way, but functional designs require you to be clever at every stage of the process. Sometimes it's actually nice just to be able to write the lengthy boilerplate code that solves the problem without having to be clever all the drat time.

I guess it's good to have both styles on tap for those times when you do have the elegant solution though. Maybe I should look into F#.

Pollyanna
Mar 5, 2005

Milk's on them.


What is functional programming poor at or incapable of, really? You can't do classes and procedural stuff, but that's kind of by definition.

gonadic io
Feb 16, 2011

>>=
Well it depends on which language that you're talking about - F# and Scala can do both objects just fine, literally every functional language that I know has a function which executes a series of side-effecting commands.

I personally am not a huge fan of using Haskell for problems which I'm working out on the fly, as changing a pure program into one that uses mutation tends to require a fair bit of refactoring (either adding another argument to your stack of functions or threading a monad everywhere). If you know ahead of time that you'll need it, or don't anticipate needing to at all then there's no problem.

Hell, I've written plenty of shell scripts in haskell trivially enough.

fart simpson
Jul 2, 2005

DEATH TO AMERICA
:xickos:

Embedded stuff?

gonadic io
Feb 16, 2011

>>=

fart simpson posted:

Embedded stuff?

Does this count?

Serenade
Nov 5, 2011

"I should really learn to fucking read"
Is there a good, offline resource for learning F#?

I spend a lot of time without internet and there's no "Learn you an F#" for me to lean on.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
Your best bet is probably to pick a bunch of good articles and save them for offline reading (can be done in most mainstream browsers). I'd start with everything on this page: http://fsharpforfunandprofit.com/site-contents/

AWWNAW
Dec 30, 2008

You can complement that by cloning some good F# GitHub repositories. A lot of the core F# stuff is open source now. Reading a bunch of (good) code usually helps me pick up a new language.

Athas
Aug 6, 2007

fuck that joker

Pollyanna posted:

What is functional programming poor at or incapable of, really? You can't do classes and procedural stuff, but that's kind of by definition.

The majority of algorithms are developed for languages that permit mutation, and porting can be awkward or lose important performance characteristics. Dynamic Programming is a class of algorithms that is often awkward (unless you can express it as a lazy array or similar).

As far as I know, it is still an open question whether pure functional programming is theoretically less performant than imperative programming, but it is easy to see that far less work has gone into purely functional algorithms.

Athas fucked around with this message at 09:09 on Aug 3, 2015

sarehu
Apr 20, 2007

(call/cc call/cc)
At any rate, there are certain abstractions you just can't use with functional programming without a performance slowdown.

Adbot
ADBOT LOVES YOU

QuantumNinja
Mar 8, 2013

Trust me.
I pretend to be a ninja.

Athas posted:

As far as I know, it is still an open question whether pure functional programming is theoretically less performant than imperative programming, but it is easy to see that far less work has gone into purely functional algorithms.

Pippenger tackled this subject in the mid-90s, comparing mutating lisp with non-mutating lisp. Here's the (quite short) paper: http://www.cs.princeton.edu/courses/archive/fall03/cs528/handouts/Pure%20Versus%20Impure%20LISP.pdf

Pippenger posted:



Of course, he's relying on specific list complexities. Applying Okasaki's techniques can crush the logarithmic factor into amortized O(1) in a lot of cases, too. Just like the sieve paper linked earlier, performant functional programming is almost always about good data structures.

QuantumNinja fucked around with this message at 14:08 on Aug 3, 2015

  • Locked thread