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
GameCube
Nov 21, 2006

man concurrentqueue does so have a peek, why did I think it didn't

maybe my problem was that it didn't have async methods. idfk. i haven't looked at this in a week and now I forget how to program.

Adbot
ADBOT LOVES YOU

VikingofRock
Aug 24, 2008




gonadic io posted:

here's how I'd implement a Fischer-Yates shuffle.

So I was thinking about this code some more, and I have another question. Let's say I wanted to extract the randomness out another layer, by making the signature shuffle :: Vector a -> Rand Vector a. What's the best way to do that? I figure that the code currently works on a RandT (St s) (Vector a), and if we can turn that into a RandT Identity (Vector a) then we are done. But I can't seem to get the types to work. If there was some function

code:
(MonadTrans t, Monad m1, Monad m2) => (m1 a -> m2 a) -> t m1 a -> t m2 a
or

code:
(MonadTrans t, Monad m) => (m a -> a) -> t m a -> t Identity a
then this would be trivial, but I'm not sure that such functions exist.

comedyblissoption
Mar 15, 2006

Awia posted:

what does he have against wait()?
Wait() and synchronously blocking on a Task<T> (using Task<T>.Result) defeats the entire purpose of the async API. there are some limited cases where blocking makes sense, but it should be the exception and not the norm.

you can unnecessarily eat up a task/thread when you synchronously block

if you simply just use the await keyword on the Task<T>, compiler magic makes it so you don't unnecessarily eat up a task/thread and you can more efficiently use hardware resources if you have a bunch of I/O or other long-running asynchronous operations

in C#, this can often mean having to bubble up Task<T> all the way up the stack though

Sapozhnik
Jan 2, 2005

Nap Ghost
I like the GNU build system a lot (autoconf, automake, pkgconfig even though that's technically separate. lol forever if you use libtool).

idk why, i know it is a yog shoggoth m4 abomination on the inside. but as a user it's so goddamn cool. openembedded be like "oh hey, looks like you used autoconf etc like a non-idiot, let me just make use of all the machinery it gives you for free to turn your source code into a cross-compiled set of packages with -debug and -devel packages totally automatically".

even the built in test runner is... somewhat serviceable, and there's a small piece of m4 you can drop in to automatically run everything through valgrind for you

i suppose it's only fitting that somebody as bad at posting as i am likes something that abbreviates to gbs

(openembedded is horrifying. but everything else that does what it does is even worse)

DrPossum
May 15, 2004

i am not a surgeon
just let sourceforge compile and distribute your binaries :shrug:

raminasi
Jan 25, 2005

a last drink with no ice

GameCube posted:

i'm tryin to avoid adding threads entirely here. c# motherfucker. async all the way. my first implementation had a single task that read the stuff from the queue and sent it but gently caress that. async.

avoiding direct calls to create threads or whatever is laudable but at the end of the day you're still going to have producer and consumer logic running concurrently and there's no real way around it

GameCube posted:

man concurrentqueue does so have a peek, why did I think it didn't

maybe my problem was that it didn't have async methods. idfk. i haven't looked at this in a week and now I forget how to program.

use a BlockingCollection

HoboMan posted:

this is probably pretty simple but speaking of asynchronous operations i got a problem for it
i want to make a collector type thing where multiple threads are by adding items to a queue for another thread to consume them as they come in
as a java dev I've never been expected to make anything fast so this is new to me (also i'm doing this in c#)

you too. you don't need to make it, it's already made.

cinci zoo sniper
Mar 15, 2013




DrPossum posted:

just let sourceforge compile and distribute your binaries :shrug:
yeah im pro-life so adware installer is a-ok

JewKiller 3000
Nov 28, 2006

by Lowtax
a new company bought sourceforge and is getting rid of all that poo poo so hopefully soon it will be cool and good again

Lutha Mahtin
Oct 10, 2010

Your brokebrain sin is absolved...go and shitpost no more!

GameCube posted:

i haven't looked at this in a week and now I forget how to program.

SAME

Bloody
Mar 3, 2013

raminasi posted:

avoiding direct calls to create threads or whatever is laudable but at the end of the day you're still going to have producer and consumer logic running concurrently and there's no real way around it


use a BlockingCollection


you too. you don't need to make it, it's already made.

hahaha gently caress me i basically reimplemented a poo poo version of that blockingcollection without even bothering to check if it existed

anthonypants
May 6, 2007

by Nyc_Tattoo
Dinosaur Gum

JewKiller 3000 posted:

a new company bought sourceforge and is getting rid of all that poo poo so hopefully soon it will be cool and good again
hahahahahahaha

GameCube
Nov 21, 2006

raminasi posted:

avoiding direct calls to create threads or whatever is laudable but at the end of the day you're still going to have producer and consumer logic running concurrently and there's no real way around it


use a BlockingCollection


you too. you don't need to make it, it's already made.

yeah after trying to figure out some other way to enforce the order of this poo poo for like four hours today I've come to the conclusion that this guy's head is so far up cleary's rear end that he cannot see the forest for the trees. adding a task that runs for the lifetime of the app may add a little complexity but how the heck else are you supposed to do it.

GameCube
Nov 21, 2006

I already implemented it that way and felt so freakin proud of myself for figuring out how to use task completion sources and poo poo. then this guy comes along and says what do you need another task for??? for this. bitch

gonadic io
Feb 16, 2011

>>=

VikingofRock posted:

So I was thinking about this code some more, and I have another question. Let's say I wanted to extract the randomness out another layer, by making the signature shuffle :: Vector a -> Rand Vector a

....
code:
(MonadTrans t, Monad m1, Monad m2) => (m1 a -> m2 a) -> t m1 a -> t m2 a

So this is easy to cheat in this specific example, as you just unwind the monad stack using runRandT instead of eval and then (after runST) you're left with the generator which you can repackage into Rand.

If you had a more complicated stack involving RandT, you could do it by unwrapping the RandT constructor to get at the StateT internal value, then unwrapping that to get at the value of type g -> ST s (a, g). Then transform that into g - > Identity (a, g) by writing a lambda that runs ST, and repackage in the StateT and RandT constructors.

I don't believe that it can be done in general with all monad transformers as you can't guarantee that they use the internal monad in such a way that you can get at it like you can with RandT. Indeed, the inflexibility of the stack is one of the bigger arguments against them - remember too that monad transformers are non commutative in general.

Just ask if you want code examples or I won't bother.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

JewKiller 3000 posted:

a new company bought sourceforge and is getting rid of all that poo poo so hopefully soon it will be cool and good again

yeah, sure, whatever

VikingofRock
Aug 24, 2008




gonadic io posted:

Just ask if you want code examples or I won't bother.

Nah that made sense. Also this reminds me that I want to look into libraries like extensible-effects more. They seem pretty interesting.

gonadic io
Feb 16, 2011

>>=

VikingofRock posted:

Nah that made sense. Also this reminds me that I want to look into libraries like extensible-effects more. They seem pretty interesting.

I was bored on the way to work, so here's a version that produces a Rand without having to thread the state manually through the ST transaction like you did in your very first (second) example:

code:
shuffle2 :: forall a g. RandomGen g => Vector a -> Rand g (Vector a)
shuffle2 vec = liftRand $ \rng -> runST $ flip runRandT rng $ actualRandomCalc
    where actualRandomCalc :: forall s. RandT g (ST s) (Vector a)
          actualRandomCalc = undefined -- as before

gonadic io fucked around with this message at 10:05 on Jul 7, 2016

Progressive JPEG
Feb 19, 2003

MALE SHOEGAZE posted:

i rly like makefiles

same except cmakelistss

Bloody
Mar 3, 2013

the wpf datagrid element is surprisingly... bad?

raminasi
Jan 25, 2005

a last drink with no ice

Bloody posted:

the wpf datagrid element is surprisingly... bad?

is it really a surprise?

also a real live member of the wpf team (which apparently still actually exists) appeared in the grey .net thread so griping there might be productive

Bloody
Mar 3, 2013

why is ui creation universally poo poo
how do so many applications manage to navigate this poo poo to create functional software

Captain Foo
May 11, 2004

we vibin'
we slidin'
we breathin'
we dyin'

Bloody posted:

why is ui creation universally poo poo
how do so many applications manage to navigate this poo poo to create functional software

users are universally poo poo so they get what they deserve

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

Bloody posted:

why is ui creation universally poo poo
how do so many applications manage to navigate this poo poo to create functional software

i have been wondering this for the last year or so too.

seems like it really hasn't improved in the last 15 years except web browsers becoming less poo poo.

Schadenboner
Aug 15, 2011

by Shine

Captain Foo posted:

users are universally poo poo so they get what they deserve


Wheany posted:

i have been wondering this for the last year or so too.

seems like it really hasn't improved in the last 15 years except web browsers becoming less poo poo.

I think it has to do with a lack of real competition in software outside the browser.

I mean, look, no one is going to convert from Oracle to %NON_SHIT_DB%, that's like asking Satan to gently caress your tight little virgin rear end in a top hat.

There's so much lock-in that there's no competition on features in most software, so there's no need to keep users happy, just "not pissed enough to take the devil's sodomy".

Also, the decision makers aren't the ones having to interact with the POS UIs, they have underlings and CJs for that sort of thing.

Schadenboner fucked around with this message at 14:19 on Jul 7, 2016

raminasi
Jan 25, 2005

a last drink with no ice
also ui design is a pretty difficult, specialized task, and there are not many people with that expertise, so there's not a community of people pushing to make the tools better. adobe products are poo poo but imagine how shittier they'd be if nobody used them.

HoboMan
Nov 4, 2010

gimp exists so you don't really have to imagine

fart simpson
Jul 2, 2005

DEATH TO AMERICA
:xickos:

Bloody posted:

why is ui creation universally poo poo
how do so many applications manage to navigate this poo poo to create functional software

its web apps but elm is pretty neat

Gul Banana
Nov 28, 2003

Shaggar posted:

if your code is like

C# code:
var result1 = await client.DoRequestAsync();
var result2 = await client.DoRequestAsync();
iirc the execution order of the awaited calls is not guaranteed, it just guarantees that both requests will be done before their results are used. async/await is fancy syntax for futures/callbacks.
this is wrong. the order is guaranteed.

uncurable mlady posted:

yes, await blocks on the caller

this tripped me up a while ago

also incorrect; the caller is suspended by the execution context. there's no blocking involved

Gul Banana
Nov 28, 2003

async is not syntax sugar for callbacks. it's syntax sugar for a state machine. when you write a method like
code:
async Task<int> f() {
  a = await foo.x();
  b = await bar.y(a);
  return b + 1;
}
then the generated IL corresponds to something like this (much simplified):
code:
class f_machine<int> {
  int state;
  Task waiter;
  int _a;
  int _b;
  int _result;
  Task MoveNext() {
    if (state == 0)
    {
      waiter = foo.x();
      return false;
    } else if (state == 1) {
      _a = waiter.Result;
      waiter = bar.y(_a);
      return false;
    } else if (state == 2) {
      _b = waiter.Result;
      _result = _b + 1;
      return true;
    }
  }
}

Task<int> f() {
  var machine = new f_machine();
  while (!machine.MoveNext())
  {
    context.yield(machine.waiter); // this returns when the current task is ready and f() can move on
    machine._state++;
  }
  return Task.FromResult(machine._result);
}
it's quite a bit more complicated in reality; it doesn't use Tasks internally and there's a methodbuilder thing which registers with the ExecutionContext and is run in steps. here's an example of how to grab the real generated code and operate the machine 'by hand': https://gist.github.com/gulbanana/5d2e2291a42e717ce73d12d2f19c8306

raminasi
Jan 25, 2005

a last drink with no ice

HoboMan posted:

gimp exists so you don't really have to imagine

lol excellent point

kitten emergency
Jan 13, 2008

get meow this wack-ass crystal prison

Gul Banana posted:

async is not syntax sugar for callbacks. it's syntax sugar for a state machine. when you write a method like
code:
async Task<int> f() {
  a = await foo.x();
  b = await bar.y(a);
  return b + 1;
}

then the generated IL corresponds to something like this (much simplified):
code:
class f_machine<int> {
  int state;
  Task waiter;
  int _a;
  int _b;
  int _result;
  Task MoveNext() {
    if (state == 0)
    {
      waiter = foo.x();
      return false;
    } else if (state == 1) {
      _a = waiter.Result;
      waiter = bar.y(_a);
      return false;
    } else if (state == 2) {
      _b = waiter.Result;
      _result = _b + 1;
      return true;
    }
  }
}

Task<int> f() {
  var machine = new f_machine();
  while (!machine.MoveNext())
  {
    context.yield(machine.waiter); // this returns when the current task is ready and f() can move on
    machine._state++;
  }
  return Task.FromResult(machine._result);
}

it's quite a bit more complicated in reality; it doesn't use Tasks internally and there's a methodbuilder thing which registers with the ExecutionContext and is run in steps. here's an example of how to grab the real generated code and operate the machine 'by hand': https://gist.github.com/gulbanana/5d2e2291a42e717ce73d12d2f19c8306

huh, neat. thanks!

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

HoboMan posted:

gimp exists so you don't really have to imagine

also blender

HoboMan
Nov 4, 2010

Wheany posted:

also blender

Sapozhnik
Jan 2, 2005

Nap Ghost
async/await owns very hard indeed and i hope java gets it soon

(so, probably sometime around 2019 at the earliest :smith: )

it's going to be a bit tough with java though since java's standard Future interface is so utterly awful and java 8's CompletableFuture took it in a very bad direction.

Bloody
Mar 3, 2013

what is worse to work with: plangers or people who smugly insist that c++ is the best because performance

HoboMan
Nov 4, 2010

it's me, i'm the rear end in a top hat who worries about performance in enterprise-grade internal apps.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

Wheany posted:

also blender

blender had an actual ui designer come in and redesign things. it's still a complex and hard to use program, but it's no longer just bad for no good reason on top of that

The MUMPSorceress
Jan 6, 2012


^SHTPSTS

Gary’s Answer
oh hey, i just sunk 20 hours into making it so you cant click cancel in a specific scenario in a specific screen. it should have been easy, but instead it was painfully hard. this code suffers from too much abstraction. observe.

problem: users can click cancel from this special subtype of record in a situation where it's not safe to do so (normally a record is created in the client and not flushed to the server until the user clicks Accept, but here the new record is an adjustment of an old record and the programmer made it so that the new record is made on the server via RPC before opening it in the client, making it indistinguishable from an existing record to the client).

solution: for this special subtype of record, set a flag when it opens in the client so that the cancel button is not available until the user takes an appropriate action on the record.

here the fun begins.
1) to create this type of record, you click an "adjust" commandbutton in the record you want to adjust.
2) this calls a function in a different file (recordtypelibrary.bas) called adjustrecord. so far so good, this code path is explicitly record adjustment
3) adjust record does this stupid rpc to build the record on the server, receiving back the id. i dont have a direct reference to a record client object here, so I cant set the flag here.
4) adjustrecord calls a function called openRecord in another file called jump.bas.
5) openRecord currently only receives the id of the record and calls a framework service (too much abstraction part 1) that creates a generic client object that's used by a special service to look up the actual object you want. this is so the same record retrieval service can be generic to many types of records. this actually ends up being a pain instead of a help most of the time.
6) since openrecord doesnt have a way to know we need to set this flag right now, i add an optional bool param to it that you can set to true if the flag must be set. openrecord doesnt have anyway to pass contextual information to the service that looks up the generic record other than to change its init parameters. this means also bolting on a new handler for this initparam to the generic service (this happens a lot, so this "generic" service is actually a giant wad of special case handlers).
7) that generic service then hands this generic record info to a "redirector" for the record type were opening. this redirector can also only receive its information via initparams. fortunately here the initparams werent used at all so it didnt get messy, but its still stupid.
8) the redirector still doesnt have a reference to an object of the actual type that contains the flag. instead, it launches a com control via our client framework and then "publishes" the record to the control. to pass the loving flag along at this step, i have to also "publish" the flag to the control.
9) the control's config file tells the framework that it needs a record of a specific type, so the framework finally at this point tries to turn that "published" generic record into an instance of the actual class containing the type of object i want, which is then stored in a global field in the control. now i can finally check that "published" flag and set it into the class for the adjust record. now i can check that flag in the cancel click handler.

to reiterate, that whole wall of text is setting a "disallowcancel" flag in an object so that you can't click the cancel button while it's set, as passed through 4 frameworks working at cross purposes.

also according to svn im the first person to touch most of these files in 6 years so i guess now im the loving expert.

HoboMan
Nov 4, 2010

congratulations


i came here to complain about my poo poo but you win, i'm wading though an italian wet dream but at least it's all in one (700 line) function

Adbot
ADBOT LOVES YOU

MrMoo
Sep 14, 2000

and somehow it's only webdev's that take the heat for being terrible.

  • Locked thread