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
baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Anyone know enough about F# scripting to help with this?

I've separated a small project out into three .fsx files to keep things organised. The first calls a function in the second, and they both refer to a union type from the third. I'm getting this fun error when I try to run the first file

code:
The type 'FSI_0002.Polls.Party' does not match the type 'FSI_0003.Polls.Party'
Both files do #load "Polls.fsx" and open Polls. Party is just a simple union type at the top of the file. They're both referencing the same thing, there's no circular dependency. How are they not the same type? The Code Lens thing in Ionide is totally fine with it too.

I'm guessing the different FSI_000x stuff is an issue, like they're in different scopes or something? I actually did get it to run when I poked at something (going from a record type using Party to a tuple with one) and thought that fixed it, but now it's decided there's a problem again. I have no idea what's going on, and I'm guessing it's something really simple, but :confused:

code:
error FS0001: This expression was expected to have type
    FSI_0019.Polls.Party
but here has type
    FSI_0020.Polls.Party
:negative: why


e- urgh looks like it's a limitation with script files. I thought it would merge into one file but apparently it's generating separate assemblies, and that's why the magic namespaces are there. Back to full-on projects I guess!

baka kaba fucked around with this message at 08:19 on Feb 17, 2017

Adbot
ADBOT LOVES YOU

NihilCredo
Jun 6, 2011

iram omni possibili modo preme:
plus una illa te diffamabit, quam multæ virtutes commendabunt

baka kaba posted:

Both files do #load "Polls.fsx" and open Polls.

If the first file loads the second, and the second loads the third, then the first one doesn't need to also load the third, it just carries over.

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Weird, I thought I already tried that. Maybe that's what made it work once and I just didn't realise. Thanks!

So I guess a script file can only open modules from files it loads directly, or from any files those files load, and so on? So in the end it's sort of recursively building up one large fsx file? And any code that relies on something 'higher up' has to either load that module itself, or something earlier has to have done it, and not both?

I'm used to the single file way of doing things, not so much splitting them up. If I want to remove this coupling, so that file2 can access the types in file3 whether it opens file1 or not, am I looking at compiling assemblies in a full project, so the loading's taken care separately of and I can just open modules directly?

Lots of ?s in there

NihilCredo
Jun 6, 2011

iram omni possibili modo preme:
plus una illa te diffamabit, quam multæ virtutes commendabunt

You're overthinking it. Here's all that MSDN has to say about the #load command:

quote:

Reads a source file, compiles it, and runs it.
That's it. #load is not some kind of dependency declaration, it's a blunt imperative command "run the stuff in this file now". When you look at it this way, it's obvious that #loading file2 executes every command contained in that file, including potentially "#load file3". And it's also obvious that if you #load both file2 and file3, you end up executing file3 twice (try it with a printf...).

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Yeah I'm just trying to get my head around what's happening. Like if you define a type twice in a single file, you get an error, but you can load it twice and it creates two separate types with the same name, the second shadowing the first.

I think I assumed running the same definition code would either give a duplicate definition error or silently overwrite the value of the globally visible type, but I guess that doesn't make sense for an interpreted script huh

raminasi
Jan 25, 2005

a last drink with no ice
It looks remarkably similar to what happens if you trick the CLR into loading two weakly-named assemblies with the same name side by side.

9-Volt Assault
Jan 27, 2007

Beter twee tetten in de hand dan tien op de vlucht.
One of the authors of the Haskell book just announced a new book for intermediate Haskell programmers: https://joyofhaskell.com

Bacchanal
Jun 25, 2003
Dread Lord of Immigration
I've been learning Elixir at work lately, and I'm kind of a strange spot when it comes to using mocks in unit tests, primarily because I don't know anyone that knows the language or culture.

Making a different set of mocks for each test in Elixir seems to be uncommon practice according to what I've found on Google, and when I search for a reason why, most people seem to directly or indirectly cite this blog post by Elixir's author. While much of what he says I don't find terribly objectionable, I was wondering if someone with more familiarity with the culture and practice of Elixir or functional programming in general could answer a few questions:

  • Why does he insist on using something like dependency injection with environment-specific mocks instead of creating mocks on a per-test basis? Is he just trying to find a "pure" Elixir solution to the problem? Am I crazy for feeling like it's an overly ceremonial approach that is difficult to scale?
  • I feel like his example might appear unobjectionable because he's chosen a single trivial case (the happy path). It seems like it is useful solely for scenarios where a call to a dependency always returns the same response. How would you use this approach to test that your code responds in the expected way to both the happy path as well as when the mocked external dependency returns one or more errors in different tests?
  • My instincts tell me to use a mocking library (e.g. mock) to mock out the dependencies of each layer of my code differently for each test to measure responses to all the possible cases of returned values from called dependencies, just like I would in any language I already know. I understand that this potentially comes at a cost in Elixir, like perhaps not being able to run tests in parallel due to global scope pollution. Is there anything else wrong with this approach? Are there any other pitfalls awaiting me if I head down this path? Is the fact that I even want to do this an indication that my code smells?

the talent deficit
Dec 20, 2003

self-deprecation is a very british trait, and problems can arise when the british attempt to do so with a foreign culture





i write elixir for work and i disagree both with the dependency injection approach and the mock approach to testing. i try to split all my functions that interact with external resources into a function that generates a symbolic request, a function that executes that request and a function that processes the return from my executor:

code:
def request(qop, het, mim) do
  %{ :endpoint => url("do/a/thing"), :method => :get, :params => params(qop, het, mim) } end

def execute(%{ :endpoint => endpoint, :method => method, :params => params }, opts) do
  :hackney.request(method, endpoint, [], params, opts)
end

def result({ :ok, 200, _, ref }) do
  ...
end
then in my tests i just test that my request function returns the correct symbolic response and my result returns the correct thing given a particular result

as long as your execute functions are straightforward this is basically equivalent to mocking but without giving up niceties like parallel test execution

the talent deficit fucked around with this message at 09:30 on Mar 4, 2017

fart simpson
Jul 2, 2005

DEATH TO AMERICA
:xickos:

That sounds kind of similar to how managed effects work in Elm and I assume also Haskell

Smoke_Max
Sep 7, 2011

I just read about the FTP controversy in Haskell and it seemed to me to have been a solid move, but one detail is still nagging me. What's the rationale behind (,)'s Foldable instance? I understand how it works, but why is it even defined? Is it a case of "because we can"? I honestly cannot see much use for it besides creating confusion (length (1, 2) = 1 says hi). Personally, by making well typed code do the wrong thing, all it does for me is make me less confident in the type checker.

(As an aside, why did it stop at (,)? What about (,,), (,,,), etc.?)

VikingofRock
Aug 24, 2008




Smoke_Max posted:

I just read about the FTP controversy in Haskell and it seemed to me to have been a solid move, but one detail is still nagging me. What's the rationale behind (,)'s Foldable instance? I understand how it works, but why is it even defined? Is it a case of "because we can"? I honestly cannot see much use for it besides creating confusion (length (1, 2) = 1 says hi). Personally, by making well typed code do the wrong thing, all it does for me is make me less confident in the type checker.

(As an aside, why did it stop at (,)? What about (,,), (,,,), etc.?)

As far as I know, (,) is Foldable pretty much exactly "because we can". It, and the Foldable instance for Either, are pretty controversial in the Haskell community for exactly the reasons you posted.

Athas
Aug 6, 2007

fuck that joker
My guess is that it's because (,) behaves like the Reader monad and Either behaves like an error monad, so they figured they should support the same operations. It's rather human-hostile, though.

Banned King Urgoon
Mar 15, 2015
The instances for (,) (and Maybe, Either, (->), et al) aren't all that useful themselves, but they're important as building blocks for higher-order constructions like Lens, Free/Cofree, etc.

Good Will Hrunting
Oct 8, 2012

I changed my mind.
I'm not sorry.
Could use some help in going from my comfortable OOP/imp Java style to Scala functional style. Basically, I have a stream of events coming in, all of which are one of a set of discrete types, and for every type we would like to have a set of "enhancement" functions executed based on the type. In Java, I'd probably just have created an "Event" class and extended that for each of the events, keeping a set of implementations of an "enhancer" function and overriding the "enhance" function in each Event extensions with the execution of all of the enhancers kept in that Set. I'm struggling a bit with how to structure this "properly" with Scala. Obviously I could probably implement it very similarly to how I did it in Java, but I don't know if that's the best method.

On a similar note, while picking up syntax and understanding what's going on behind the scenes of Scala -> JVM code, picking up the functional paradigms has been hard for me.

Asymmetrikon
Oct 30, 2009

I believe you're a big dork!
I'm not super familiar with Scala, but from a Haskell POV, you might have an Event ADT like:
code:
type Event
    = ClickEvent Click
    | KeyEvent Key
    | FooEvent Foo
and if you had an enhancement for Click, Key, and Foo, you'd make a function:
code:
enhance :: Event -> Event
enhance (ClickEvent click) = ClickEvent $ enhanceClick click
enhance (KeyEvent key) = KeyEvent $ enhanceKey key
enhance (FooEvent foo) = FooEvent $ enhanceFoo foo
where enhanceClick, enhanceKey, and enhanceFoo are specific enhancers for each sub-type.

That's if the enhancement function for each sub-event type returned the same type of event; otherwise, you'd either have to add more things to the Event or make an EnhancedEvent or something.

Good Will Hrunting
Oct 8, 2012

I changed my mind.
I'm not sorry.
Everything could return the same event type. Basically I need to turn a JSON record like {eventType, timestamp, key} into {eventType, timestamp, key, enhancement1, enhancement2, enhancement3} where those "enhancements" are just results of running the enhancement functions which range from a few calculations to lookups in local files.

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Like Asymmetrikon's saying, I guess you want something like this?

Serenade
Nov 5, 2011

"I should really learn to fucking read"
For Markov chain generation, am I incorrect in assuming it would basically use map / filter to create and clean tokens, then a reduce to boil down the list of tokens to a dictionary of Tokens mapped to tuples of weight and tokens?

I've been meaning to make a reusable one for a long time and want to use it as an excuse to further practice F#.

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

I made one in F# (that was probably bad) that basically created a sequence of tokens, used windowed and map to create pairs in tuples, and then folded those into an empty Map. The folding function looked up Token1 in the map, which returned another map of all the following tokens and their counts. Then it checked that for Token2 and either incremented its count or added it as a new entry. Then after the fold it did a map converting all those counts to normalised weights

You could use a mutable Dictionary too but I was trying to be :pcgaming:functional as hell:pcgaming:

Serenade
Nov 5, 2011

"I should really learn to fucking read"

baka kaba posted:

I made one in F# (that was probably bad) that basically created a sequence of tokens, used windowed and map to create pairs in tuples, and then folded those into an empty Map. The folding function looked up Token1 in the map, which returned another map of all the following tokens and their counts. Then it checked that for Token2 and either incremented its count or added it as a new entry. Then after the fold it did a map converting all those counts to normalised weights

You could use a mutable Dictionary too but I was trying to be :pcgaming:functional as hell:pcgaming:
That's helpful as hell. This is mostly my plan but I didn't know windowed exists and I was thinking of fold, not reduce. Thanks.

At this moment I'm not interested in being true doom functional, but the siren's song of parallel programming is always alluring.

Athas
Aug 6, 2007

fuck that joker

Serenade posted:

At this moment I'm not interested in being true doom functional, but the siren's song of parallel programming is always alluring.

Much like the sirens of myth, functional parallel programming mostly just leads to a lot of wrecks.

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

In this case I don't think using a Map over a Dictionary is that much of a change, from a coding perspective at least. It's not like Array2D hell or anything. Try it out!

KernelSlanders
May 27, 2013

Rogue operating systems on occasion spread lies and rumors about me.

baka kaba posted:

Like Asymmetrikon's saying, I guess you want something like this?

Yeah, match/case is a really powerful construct and tends to be underused by everyone in scala, especially beginners. It should not only replace isInstanceOf but also things like isEmpty, contains, etc.

raminasi
Jan 25, 2005

a last drink with no ice

Serenade posted:

That's helpful as hell. This is mostly my plan but I didn't know windowed exists and I was thinking of fold, not reduce. Thanks.

At this moment I'm not interested in being true doom functional, but the siren's song of parallel programming is always alluring.

F# has pairwise now so you don't need to deal with incomplete pattern matching off the output of windowed :science:

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Oh nice - brand new in... 2.0? :catstare:

NihilCredo
Jun 6, 2011

iram omni possibili modo preme:
plus una illa te diffamabit, quam multæ virtutes commendabunt

baka kaba posted:

Oh nice - brand new in... 2.0? :catstare:

My co-worker was so proud of having written a 'proper' pure recursion-based utility function for a piece of layout code we needed, it made me a little sad to have to tell him "that was nice, now delete it and replace it with a single call to List.chunkBySize".

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

I definitely haven't done anything like that before, heheheeeeeeh

Sometimes it's good to just type something like Option and see what functions it exposes, there's a lot of useful stuff just waiting for you to implement yourself like a caveman leverage elegantly. I wish Microsoft's documentation site wasn't dog slow because you could learn a lot casually browsing that too

Good Will Hrunting
Oct 8, 2012

I changed my mind.
I'm not sorry.
Is "cake pattern" the only way to mock out something like this? I need to mock out MaxmindDatabases.getConnectionTypeResult in a unit test but you can't mock objects. I guess another option is to create a companion object of the class and access it like that? I'm brand new to Scala so I really can't evaluate tradeoffs of such things too well.

code:
object MaxmindDatabases {
  lazy val CONNECTION_TYPE_READER: DatabaseReader = initializeDb(ConnectionTypeFile.fileName)

  def getConnectionTypeResult(ipAddress: InetAddress): ConnectionTypeResponse = {
    CONNECTION_TYPE_READER.connectionType(ipAddress)
  }

  def initializeDb(mmdbFile: String): DatabaseReader = {
    //bunch of useless crap
  }
}

Sedro
Dec 31, 2008

Good Will Hrunting posted:

Is "cake pattern" the only way to mock out something like this? I need to mock out MaxmindDatabases.getConnectionTypeResult in a unit test but you can't mock objects. I guess another option is to create a companion object of the class and access it like that? I'm brand new to Scala so I really can't evaluate tradeoffs of such things too well.

I don't think the cake pattern will help here. If you're new to scala, you're better off pretending the cake pattern doesn't exist.

The solution is the same as other languages:
1. Create a trait (interface) containing the public API
2. Accept an instance of the trait instead of referencing the singleton object
3. Use a mock implementation in your tests

code:
trait DatabaseConnection {
  def getConnectionTypeResult(ipAddress: InetAddress): ConnectionTypeResponse
}

object MaxmindDatabases extends DatabaseConnection {
  lazy val CONNECTION_TYPE_READER: DatabaseReader = initializeDb(ConnectionTypeFile.fileName)

  def getConnectionTypeResult(ipAddress: InetAddress): ConnectionTypeResponse = {
    CONNECTION_TYPE_READER.connectionType(ipAddress)
  }

  def initializeDb(mmdbFile: String): DatabaseReader = {
    //bunch of useless crap
  }
}

class ThingThatUsesDatabase(dbs: DatabaseConnection)

// prod:
new ThingThatUsesDatabase(MaxmindDatabases)

// test:
new ThingThatUsesDatabase(new DatabaseConnection { /* mock stuff */ })

Good Will Hrunting
Oct 8, 2012

I changed my mind.
I'm not sorry.
I'm half asleep right now so I'll give this a shot tomorrow but I think the thing tripping me up was that a few things I was trying to mock were Objects which can't be mocked as easily as classes. I have a parent class that has a function with an arbitrary number of Objects being called and those functions don't really make sense as classes because they'll never have any non-instance properties or anything so I made them Scala objects. I guess I could change everything to classes, expose via companion, and mock accordingly.

xtal
Jan 9, 2011

by Fluffdaddy
Any of you guys hosed with Idris? 1.0 just came out and I want to use it but there's still no package manager...

Asymmetrikon
Oct 30, 2009

I believe you're a big dork!
Haven't used it since they moved from Effects to Control.ST (still wrapping my head around that), probably going to get back into it now that it's got a concrete release and see if I can contribute. A package manager would definitely be a good thing.

Doc Hawkins
Jun 15, 2010

Dashing? But I'm not even moving!


I haven't but it sounds like a perfect opportunity to start using nix. :v:

More seriously, it looks like support is still highly bare-bones and you'd have to write all the package definitions yourself except for the three already in nixpkgs. Meaning you'd have to learn another new language at the same time, which I would never unsarcastically recommend.

But! Nix is great! And people who already know Idris should learn nix and contribute to nixpkgs! Hence my responding with something that doesn't really help you!!

xtal
Jan 9, 2011

by Fluffdaddy
Having Idris use a general package manager would be way better than building another package manager for every single language but Nix looks kind of hacky and cruddy tbh

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

xtal posted:

Any of you guys hosed with Idris? 1.0 just came out and I want to use it but there's still no package manager...
I used to contribute to Idris. These days I use (and occasionally contribute to) Rust instead, because it is actually intended to be a useful language for building things, and that's what I'm interested in doing. Still really excited about dependent types, but I guess it's not their time yet.

xtal posted:

Having Idris use a general package manager would be way better than building another package manager for every single language but Nix looks kind of hacky and cruddy tbh
Nix is the best thing since sliced bread. 17.03 just got released, including my work to get Vulkan working! Gotta say I'm a big fan of how open the Vulkan-related Khronos processes are to community involvement; upstreaming the relevant patches was very smooth.

Doc Hawkins
Jun 15, 2010

Dashing? But I'm not even moving!


xtal posted:

Having Idris use a general package manager would be way better than building another package manager for every single language but Nix looks kind of hacky and cruddy tbh

I love it but I totally understand this impression. If you like the concept, maybe look at guix ("geeks") instead?

KernelSlanders
May 27, 2013

Rogue operating systems on occasion spread lies and rumors about me.
Looks like the Scala thread got nuked. Has anyone used any of the various GIS libraries for Spark? More importantly do you have one you like? Most of the APIs seem to have been written by someone who doesn't understand why the existing Spark API is designed the way it is.

Colonel Taint
Mar 14, 2004


I'm going to ask here, because the LISP thread is archived -

I've been on a bit of a lisp kick lately trying to grasp what everyone who argues for lisp is raving about. I've been going through SICP and glancing through the freely available common lisp books and some articles online. What I don't understand is, it seems a big point a lot of people try do drive home is that one can 'extend the language' by basically writing functions. How is this any different from writing functions in, say, C? I could write a bunch of higher level functions that build on the standard C library, but I never would think of that as extending the language. I understand macros are a separate story, but am I missing something important here?

Adbot
ADBOT LOVES YOU

xtal
Jan 9, 2011

by Fluffdaddy
Yes. The difference is that Lisp has first class functions and also macros. First class functions let you build things from very small components like map and fold. Macros allow you to implement​ your own control flow structures which is not possible with C (afaik.)

  • Locked thread