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
CPColin
Sep 9, 2003

Big ol' smile.

Why do I work there or why do I have a free account? I work there because it's a paycheck and they hired me right out of college in 2007. I have a free account because everybody who works there gets one! It's a perk!

Adbot
ADBOT LOVES YOU

HoboMan
Nov 4, 2010

i'm sure it's impossible for you as a dev to just give yourself one if you really wanted.

aardvaard
Mar 4, 2013

you belong in the bog of eternal stench

that's not a perk. that's probably the only way they get users.

CPColin
Sep 9, 2003

Big ol' smile.
I thought this page specifically identified it as a perk, but I guess not. Never mind!

HoboMan
Nov 4, 2010

ok so I'm referencing System.Web.dll but I can't use the namespace System.Web.UI????

VikingofRock
Aug 24, 2008




So I've got a question about parsing things in Haskell using Megaparsec.

I've got a fairly regular file format which is output by some of my collaborations tools which I am trying to write a parser for. There are a few things that come out of this file, but one of those things is a data structure that looks roughly like this:

code:
data GalaxyCluster = GalaxyCluster {
    center :: Position,
    radius :: Distance,
    redshift :: Double,
    luminosity :: Maybe Double -- might not have been measured
    signalToNoiseRatio :: Maybe Double -- ditto
}
The section of the file that this comes from looks roughly like this:

code:
...
GalaxyCluster1
center: (12.3, 45.6)
radius: 300
redshift: 0.5
luminosity: 3.0
signalToNoiseRatio: 101.5
GalaxyCluster2
radius: 600
redshift: 0.34,
luminosity: 8.0,
center: (32.1, 6.54)
GalaxyCluster3
...
So the issue is that those fields can be given in any order in the file (though they are all contiguous). The non-maybe fields must occur exactly once, and the maybe fields may occur once or not at all (in which case they are Nothing). So I think I need some way to parse all those lines, and then validate stuff afterwards. My currently plan is to create a helper data structure like this:

code:
data GalaxyClusterParts = GalaxyClusterParts {
    m_center :: Maybe Position,
    m_radius :: Maybe Distance,
    m_redshift :: Maybe Double,
    m_luminosity :: Maybe Double
    m_signalToNoiseRatio :: Maybe Double
}
and then do some sort of monadic iteration over those lines using a function like updateParts :: GalaxyClusterParts -> Parser GalaxyClusterParts, which takes the current GalaxyClusterParts returns that GalaxyClusterParts updated with the new information. So that if the read-in line was "redshift: 0.34", it would return a GalaxyClusterParts with m_redshift set to Just 0.34. Then when I reach a line which is not an attribute of the Galaxy Cluster, I can go back and make sure that all of the required fields are Justs, and call "fail" otherwise. Also I can call fail in updateParts if the field is already a Just.

That seems a little gross though, and very boilerplate heavy. Usually in Haskell that means there is a better way. So does anyone know of a better way to go about this?

VikingofRock
Aug 24, 2008




Oh holy crap I guess that's what Text.Megaparsec.Perm is for. Dunno how I missed that, but that makes things much easier.

Nevermind I guess.

Valeyard
Mar 30, 2012


Grimey Drawer
This country is hosed

gonadic io
Feb 16, 2011

>>=

Valeyard posted:

This country is hosed

oh god what's happened now? last i heard both pm candidates were p vile but that's old news

Valeyard
Mar 30, 2012


Grimey Drawer

gonadic io posted:

oh god what's happened now? last i heard both pm candidates were p vile but that's old news

they shut down the Taco Mazama food place by my work for refurbishment :negative:

AWWNAW
Dec 30, 2008

this country will continue to be hosed as all hell until everyone learns what a monad is

LordSaturn
Aug 12, 2007

sadly unfunny

AWWNAW posted:

this country will continue to be hosed as all hell until everyone learns what a monad is

since I now have an excuse to mention monads:

someone in a gamedev thread was talking about LINQ and mentioned that buttList.Select( Foo ).Where( Bar ).From( Bat ).ToList() doesn't actually execute Foo Bar or Bat until you call ToList, and then iterates over the input exactly once, and suddenly I understood why anyone cares about monads

gonadic io
Feb 16, 2011

>>=

LordSaturn posted:

since I now have an excuse to mention monads:

someone in a gamedev thread was talking about LINQ and mentioned that buttList.Select( Foo ).Where( Bar ).From( Bat ).ToList() doesn't actually execute Foo Bar or Bat until you call ToList, and then iterates over the input exactly once, and suddenly I understood why anyone cares about monads

also note that any exceptions thrown in Foo or Bar or Bat will escape a try/catch put around that any statement until the ToList lol

AWWNAW
Dec 30, 2008

lazy evaluation is awesome and terrible. respect it

cinci zoo sniper
Mar 15, 2013




i opened tiobe index for first time in a while and i have to ask now, where are used delphi/object pascal, and groovy

Sapozhnik
Jan 2, 2005

Nap Ghost

LordSaturn posted:

since I now have an excuse to mention monads:

someone in a gamedev thread was talking about LINQ and mentioned that buttList.Select( Foo ).Where( Bar ).From( Bat ).ToList() doesn't actually execute Foo Bar or Bat until you call ToList, and then iterates over the input exactly once, and suddenly I understood why anyone cares about monads

that's not monads though that's lazy evaluation

VikingofRock
Aug 24, 2008




Mr Dog posted:

that's not monads though that's lazy evaluation

The monads are arguably what make it single pass.

LordSaturn
Aug 12, 2007

sadly unfunny

lazy eval is related only as it's an obvious answer to "why do you guys keep saying that the monad determines when the lambda executes". also I didn't know LINQ did that because I am an autodidact w.r.t. C#

so here, does this work/make sense?
code:
buttMonad = buttList.Select( Foo );
buttList1 = buttMonad.Select( Bar ).ToList();
buttList2 = buttMonad.Select( Bat ).ToList();
like, this is a thing the monadic implementation of lazy eval in LINQ can do that a normie implementation of lazy eval could not

HoboMan
Nov 4, 2010

man, making a linq select extension for the DataTable class has been the single most useful thing i ever done

comedyblissoption
Mar 15, 2006

Mr Dog posted:

that's not monads though that's lazy evaluation

comedyblissoption
Mar 15, 2006

Wheany posted:

robot and cucumber
actually it was a homegrown testing framework and fitnesse

cucumber was the one that was recommended

comedyblissoption
Mar 15, 2006

also you can have monads without lazy evaluation, they are orthogonal

an example of a monad would be List

where SelectMany is the bind operator and the List constructor is the unit operator

Luigi Thirty
Apr 30, 2006

Emergency confection port.

redoing my polygon renderer to like, actually make sense and junk

here's some wireframe rotation on 2 axes

comedyblissoption
Mar 15, 2006

LordSaturn posted:

since I now have an excuse to mention monads:

someone in a gamedev thread was talking about LINQ and mentioned that buttList.Select( Foo ).Where( Bar ).From( Bat ).ToList() doesn't actually execute Foo Bar or Bat until you call ToList, and then iterates over the input exactly once, and suddenly I understood why anyone cares about monads
the most cool thing about lazy evaluation is that something like
code:
numbers
    .Where(x => x > 100)
    .Where(IsPrime)
    .Skip(10)
    .Take(5)
    .Select(x => x * 100)
    .ToList()
will not have to iterate over all of the numbers in number in order to do its logic

it just needs to iterate enough to have found the first 15 prime numbers that are greater than 100. if there's not enough numbers for this it handles that case elegantly too.

it allows you to chain collection processing functions together in an almost declarative way instead of handrolling your own for loops

the worst thing about the stdlib linq in C# is that it's generally slower than the equivalent handrolled for loops and there's a lot of heap allocation going on

rustlang proves that this style of collection processing doesn't actually need to incur a runtime penalty

rustlang's iteration can be faster than handrolled C-like for loops (guarantees lack of mutable aliasing)

comedyblissoption fucked around with this message at 01:15 on Jul 9, 2016

comedyblissoption
Mar 15, 2006

also uh you should always prefer using linq over the equivalent for loops in C# unless you have a performance reason not to

games unfortunately afaik want you to minimize heap usage due to the garbage collector pauses so you might be hosed there

LOOK I AM A TURTLE
May 22, 2003

"I'm actually a tortoise."
Grimey Drawer

comedyblissoption posted:

the worst thing about the stdlib linq in C# is that it's generally slower than the equivalent handrolled for loops and there's a lot of heap allocation going on

is the heap allocation bit because of the lambdas? theyre adding nested functions in c#7, and i believe one of the reasons is that it lets people cut back on lambdas a bit without having to pollute the class scope with one-off functions

C# code:
List<int> Primes()
{
    bool CantBeTiny(int x) => x > 100;
    int MustBeHuge(int x) => x * 100;

    return numbers
        .Where(CantBeTiny)
        .Where(IsPrime)
        .Skip(10)
        .Take(5)
        .Select(MustBeHuge)
        .ToList()
}
itll take some getting used to though

Sapozhnik
Jan 2, 2005

Nap Ghost

comedyblissoption posted:

games unfortunately afaik want you to minimize heap usage due to the garbage collector pauses so you might be hosed there

lolunity

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

LOOK I AM A TURTLE posted:

is the heap allocation bit because of the lambdas? theyre adding nested functions in c#7, and i believe one of the reasons is that it lets people cut back on lambdas a bit without having to pollute the class scope with one-off functions

C# code:
List<int> Primes()
{
    bool CantBeTiny(int x) => x > 100;
    int MustBeHuge(int x) => x * 100;

    return numbers
        .Where(CantBeTiny)
        .Where(IsPrime)
        .Skip(10)
        .Take(5)
        .Select(MustBeHuge)
        .ToList()
}
itll take some getting used to though

you'd think that the compiler would be able to make those equivalent, at least in cases where the lambda only refers to its arguments and nothing else from the containing scope

comedyblissoption
Mar 15, 2006

there's a bunch of reasons why linq may be slower than for statements here
http://stackoverflow.com/a/2675061:

quote:

  • LINQ uses delegate calls excessively, and delegate invocations are (a very tiny bit) slower than method invocations and of course slower than inline code.
  • A delegate is a method pointer inside an object. That object need to be created.
  • LINQ operators usually return a new object (an iterator) that allows looping through the collection. Chained LINQ operators thus create multiple new objects.
  • When your inner loop uses objects from outside (called closures) they have to be wrapped in objects as well (which need to be created).
  • Many LINQ operators call the GetEnumerator method on an collection to iterate it. Calling GetEnumerator usually ensures the creation of yet another object.
  • Iterating the collection is done using the IEnumerator interface. Interface calls are a bit slower than normal method calls.
  • IEnumerator objects often need to be disposed or at least, Dispose has to be called.

you can even look at something like the List source here to see what extra work it may be doing:
http://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs

you'll notice that the list's Enumerator MoveNext does extra work just to ensure you don't invalidate the enumerator/iterator by using a special _version field

to even use IEnumerable.Where, maybe you are forced to box the list enumerator inside an IEnumerable even though the list enumerator is a struct? not sure about any of this and you should profile if it matters, but it raises a lot of questions about performance

comedyblissoption fucked around with this message at 04:40 on Jul 9, 2016

comedyblissoption
Mar 15, 2006

rustlang may show you don't need to trade expressiveness for performance so you can have the best of both worlds

c++ has iterators and lambdas and poo poo but holy gently caress at the syntax

comedyblissoption fucked around with this message at 04:47 on Jul 9, 2016

Bloody
Mar 3, 2013

comedyblissoption posted:

the most cool thing about lazy evaluation is that something like
code:
numbers
    .Where(x => x > 100)
    .Where(IsPrime)
    .Skip(10)
    .Take(5)
    .Select(x => x * 100)
    .ToList()
will not have to iterate over all of the numbers in number in order to do its logic

it just needs to iterate enough to have found the first 15 prime numbers that are greater than 100. if there's not enough numbers for this it handles that case elegantly too.

it allows you to chain collection processing functions together in an almost declarative way instead of handrolling your own for loops

the worst thing about the stdlib linq in C# is that it's generally slower than the equivalent handrolled for loops and there's a lot of heap allocation going on

rustlang proves that this style of collection processing doesn't actually need to incur a runtime penalty

rustlang's iteration can be faster than handrolled C-like for loops (guarantees lack of mutable aliasing)

and numbers can just be:

IEnumerable<int> Numbers()
{
int i;
while(true) yield i++;
}

infinite collections own

The MUMPSorceress
Jan 6, 2012


^SHTPSTS

Gary’s Answer
remember that poo poo I was bitching about yesterday? today I retrofitted it. 23 files in 3 directories, each 1000+ loc with one at 25000 loc. even using kdiffs directory merge feature to merge the current branch into the retro branch (hell no our svn can't do that on its own) it took 6 hours to get everything right because of the differences between versions. for some reason nobody else knows how to do this poo poo.

GameCube
Nov 21, 2006

Luigi Thirty posted:

redoing my polygon renderer to like, actually make sense and junk

here's some wireframe rotation on 2 axes



hell yes!!!

GameCube
Nov 21, 2006

wheres ur github

Xarn
Jun 26, 2015

comedyblissoption posted:

rustlang may show you don't need to trade expressiveness for performance so you can have the best of both worlds

c++ has iterators and lambdas and poo poo but holy gently caress at the syntax

I actually enjoy C++. :shrug:

But chaining poo poo linq-like with iterators is such a huge pain, nobody does it anyway, we just wait for ranges to make it into C++ standard (or use the prototype library), so that we don't have to deal with that poo poo.

oh no blimp issue
Feb 23, 2011

Luigi Thirty posted:

redoing my polygon renderer to like, actually make sense and junk

here's some wireframe rotation on 2 axes



cool as poo poo

this is as far as my own renderer has got so far

Soricidus
Oct 21, 2010
freedom-hating statist shill
c++ iterators are horrible. an entire generation of painfully bad apis because someone thought it would be cute to use operator overloading to make it so you could use c pointers as iterators too.

hobbesmaster
Jan 28, 2008

Xarn posted:

I actually enjoy C++. :shrug:

But chaining poo poo linq-like with iterators is such a huge pain, nobody does it anyway, we just wait for ranges to make it into C++ standard (or use the prototype library), so that we don't have to deal with that poo poo.

what you don't like writing
for( std::vector<foo_t>::iterator bar = baz.begin(); bar != baz.end(); bar++)
all the time?

~Coxy
Dec 9, 2003

R.I.P. Inter-OS Sass - b.2000AD d.2003AD

Wheany posted:

Theory: let's use a dsl so that non-coders can write <whatever code>
Reality: non-coders still won't write code and coders want to use an actual programming language.

architect spent several days defining a "dsl" (i.e. plain old c# with convenience functions) to write automated integration tests

result:
1) testers only ever executed tests someone else had written. we had to add a function that let them use an excel spreadsheet to call tests with arguments
2) as the programmer I wanted to write and run my tests in an IDE so I had to c/p everything back and forwards each time
3) end product was less featureful and less useful than just using nunit

~Coxy fucked around with this message at 13:29 on Jul 9, 2016

Adbot
ADBOT LOVES YOU

Xarn
Jun 26, 2015

hobbesmaster posted:

what you don't like writing
for( std::vector<foo_t>::iterator bar = baz.begin(); bar != baz.end(); bar++)
all the time?

Meh, either write it as for (auto bar = baz.begin(); bar != baz.end(); ++bar) or as
for (auto& elem : baz) { ... }


The real pain, comes when you want to make something lazily generated, like this
code:
numbers
    .Where(x => x > 100)
    .Where(IsPrime)
    .Skip(10)
    .Take(5)
    .Select(x => x * 100)
    .ToList()
because the current C++ standard has no story for you at all, so you would have to start either writing your own range library (or stealing Range v3 if you aren't compiling under MSVC), fuckton of iterator adapters and various glue utilities. Also there is a ton of fun to be had with invalidation and lifetimes. :v:

  • Locked thread