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
MononcQc
May 29, 2007

A thread for all

Adbot
ADBOT LOVES YOU

MononcQc
May 29, 2007

Martytoof posted:

how do i make a webpage with it

with a form and ecommerce and a sweet flash intro

quit baitin' me I would legit help you martytoof :argh:

MononcQc
May 29, 2007

Werthog 95 posted:

ayup

school doesn't teach you how to write c++, it uses c++ to teach you data structures or algorithms or whatever. still undoing all that damage of profs writing C in C++

I don't want to go back onto the "how to teach programming" topic that's been covered fruitlessly countless times, but I still remember students struggling more with C++ than with the data structures they were to be taught in data structure classes. Insert some lisp advocacy comment somewhere.

MononcQc
May 29, 2007


http://www.dangermouse.net/esoteric/piet.html

uses images as a programming language.

MononcQc
May 29, 2007

I would be so amazed to have to maintain code like that that I might just silently deal with it, in a strange mix of hatred and respect.

MononcQc
May 29, 2007

Ronald Raiden posted:

why do we have 3 programming threads now can't we keep this all in one place. I don't want to read 3 whole threads.

I guess we can do this the day there just one phone thread.

MononcQc
May 29, 2007

super easy way to deflate wages, without immigration: allow people to work remotely, let them live in bumfuck nowhere and pay them competitive prices according to where they live. near-shoring supremacy.

MononcQc
May 29, 2007

Cocoa Crispies posted:

i won't lie, i'm thinking of moving out of metro miami basically so i get a raise without more money

Still at the same job btw? I'll be in SF for a few days for work in June (10-15) if you're around during that time.

MononcQc
May 29, 2007

dur posted:

hey

do any of you guys have recommendations for books?? i've only done like 3/4 of that "learn python the hard way" book so i think i need like babbys programming fundamentals

and also a reason to write lots of code because my job sure isn't letting me do that

I learned a ton reading SICP and doing most of the exercises, but I already had the basics down and it took months to go through still. It's one of the books I'm really happy to have gone through. How To Design Programs might be more accessible, but I have never tried it.

If you want to know why things are like they are -- how is computer formed -- I think Code: The Hidden Language of Computer Hardware and Software is a very nice introductory text. I started with high-level languages from the beginning and reading it had me going "oooh that's how!"

For more direct hands-on programming books, I don't have a lot of recommendations, though. It's probably easier to go with something language-specific which would be adapted for a specific task you want to accomplish in the end, rather than going "hey, how do I program in general?"

MononcQc
May 29, 2007

MVC is not about state machines, but about how you break up components of a system.

It basically means that a given set of classes/modules take care of dealing with the 'model', or how you represent your data and state in memory or in disk, another set takes care of the 'view', or how to use the data in the model and display them to the user, and a controller is the set of classes or modules that deal with representing events, calling for poo poo to be changed.

- The view basically only gets stuff from the model and whatever the controller gives it to display content.

- The model is called both by the controller and the view. Usually the view only calls for read-only operations.

- The controller is going to receive user events, and ask the model to change data, or tell the view to alter how things are represented.

MVC is often used as the name of something called "MVP", or "Model-View-Presenter". In MVP:

- The view blindly receives data to be displayed. The data will usually come from the Presenter.

- The Model still represents data, but is only called by the Presenter, which will both read, write, and whatnot from it. The View doesn't know about the Model.

- The Presenter is the middle man that contains all the logic between the model and the view and glues them together. It will take user input, do whatever it needs with the model about it, and provide whatever data the view needs to have to present back to the user.

People will use MVC for both of these approaches rather interchangeably, though. MVC (and MVP) are both higher level ways to describe architecture patterns, and don't have much to do with state of the application as it executes as much as it has to do with how code is split up and responsibilities are divided across components of the code base.

MononcQc
May 29, 2007

prefect posted:

easy solution: establish what the TRUE TIME is, and measure everything from there. the past is a foreign country; we don't have to care about hurting their feelings

sorry, due to acceptance of your proposal, your employment contract is no longer valid as we cannot for sure know how long you've been here and will prepare to start from scratch. please note that your medical records have been similarly destroyed.

MononcQc
May 29, 2007

any non-lovely datetime API is likely wrong because datetime APIs are wrong and terrible IRL.

MononcQc
May 29, 2007

I like when people say timezones offsets are easy, and then you look at their code and they don't handle timezones on a half hour offset, or those that are at 15 or 45 minutes offset.

MononcQc
May 29, 2007

polpotpi posted:

theres three time zones you need to care about because they cover like 90% of the market you actually want to sell to.

Eastern, Central, Pacific

:canada: Central, Mountain, Pacific, Eastern, Atlantic, Newfoundland Standard (:argh:)
                                  :quebec:

MononcQc
May 29, 2007

yase it happens whenever you take the time to understand your own code but not the code of others and suddenly you're like "but how!!"

MononcQc
May 29, 2007

qntm posted:

and this is useful because

It's been a while since I've read on that so I might be wrong, but Church numerals are basically equivalent to Peano arithmetics, which are proven to be complete and undecidable and also mean that you can express pretty much any logical system you want with it. It basically yells you lambda calc can be equivalent to any other similar logical system (ZF set theory and whatnot).

It's fairly important to guys like Douglas Hofstadter who love that poo poo, and mathematicians that used it in whatever proof system they wanted to make stuff progress, I guess.

MononcQc
May 29, 2007

if this is the case I recommend that being able to implement peano numbers or the equivalent of church-numerals from pi-calc is a good basic requirement in order to be good at concurrent/distributed/actor stuff.

MononcQc
May 29, 2007

if you work with coworkers who are really pushy about what editor or IDE you should use (instead of just trying to sell you some advantages of theirs or whatever), they're terrible people and don't listen to them.

Although I once gave training classes to a guy who used notepad.exe to program and it wasn't the best of ideas.

MononcQc
May 29, 2007

Single assignment owns and hell yes functional programming chat

MononcQc
May 29, 2007

Pollyanna posted:

lambda is new to me. i havent seen that before.

also in that example, don't the for loop and the lambda do basically the same thing, if i'm reading it correctly?


so the only way to define a sorted version of l is to say:

ls = sort(l)

? you can't change l itself? that doesn't seem like too much of a big deal...

Yes and no. That depends on the language. Immutability and single assignment are not necessarily the same exact thing.

Let's say I have a tree T:

code:
      d
    /   \
   b     g
 /  \   /  \
a    c f    h
Now let's say my code does:

code:
Old = T, % regular assignment
New = Old,
New = insert(e, New)
Now here, in a language like Erlang or Haskell or whatever, you would crash (or not compile) because you're trying to change the value of a variable. However, nothing keeps you from having a language where you allow that as long as Old remains usable, and New =/= Old once the update has taken place.

This can be done with immutability, which pretty much all functional languages support. When you update the tree, nodes that are in common are kept, and otherwise part of the tree points to the old one, giving you something a bit like this in memory:



Basically, the entire unchanged subtree starting at b is kept for both Old and New trees, but the rest changes in some way. The h node is also shared because it had no reason to change. The F node had to be copied and rewritten to allow to change what child it has, but note that if the content of F is large, that can be copied literally. I.e. if my node is {Current, Left, Right}, I need to change the node, but could still point to the existing 'Current' value from the older tree.

Garbage collection will later determine what can be reused or not. This lets you update trees in O(log n) memory as well as time, rather than O(n) memory if no sharing took place and deep copies were needed, regardless of the content of the nodes.

So single assignment is often used, but is not necessary for a language to be immutable.

In the case above, doing the update and allowing New to point to the tree in red would work, and Old could still keep its references intact and also work, despite New (the variable) changing definition over time. The data structure remained safe for all its users, though.

MononcQc fucked around with this message at 13:33 on Sep 26, 2013

MononcQc
May 29, 2007

Pollyanna posted:

okay, so say i wanted to make a program return the number 7.

<...snip...>

so functional programming doesn't like that, and prefers x = 2 and y = x + 5? but wouldn't the steps basically be the same for that? you'd see that y = x + 5, but you don't know what x is, so you look backwards in the program for x's initial state...

you see what i mean? it's the same number of steps.

Functional programming basically takes a more mathematical approach to things.

So if you're in elementary school and the teacher tells you

code:
One = 1
Two = 2
Three = One + Two
Four = Two + Two
Four = One + Three
You should be able to freely substitute:


code:
3 = 1 + 2
4 = 2 + 2
4 = 1 + 3
However, when programmers come in and decide that variables are actually memory locations and these can be modified, precious mathematicians feel confused because:

code:
One = 1
Two = 2
Three = One + Two
Four = Two + Two
Four = One + Three
One = Two
Four = One + Two
Would be substituted as

code:
3 = 1 + 2
4 = 2 + 2
4 = 1 + 3
1 = 2
4 = 1 + 2
Which is visibly weird and hard to think about! Functional programming with regards to variables isn't about being economical on lines and whatnot, but more or less about using variables the way mathematicians can use them -- a fixed value you can reason about, and not a memory location or pointer or less abstract concept.

Because of that, making variables immutable works fairly well. In some languages with single assignment, you can reassign to variables as long as the value remains the same. So that:

code:
x = 1,
x = 0+1,
x = 2
will work for the first 2 assignments, but will raise an exception (or crash, or won't compile) on the third one, as if it were an assertion.

MononcQc
May 29, 2007

Pollyanna posted:

nice. that makes a lot of sense. in your example, haskell and erlang are immutable AND single assignment, right? hence why you can't change New. in languages that are immutable but not single assignment, you can still change New.
is that correct?

Yes. Erlang and Haskell are both immutable and single assignment. In languages without single assignment and immutability, you can still change new indeed. Elixir does this on the BEAM virtual machine, for example. You can coerce a variable to be single assignment by prefixing with ^ so that:

code:
x = 1
x = 2
^x = 3
Will work up until the last expression, where ^x tells the compiler (or interpreter) "please reuse the 'x' from the previous value rather than reassigning".

Pollyanna posted:

the way i had understood the whole "x = 1, y = x, print y + 1" thing is that like...there's a difference between y being equal to the same value/string/whatever that x is, and y being literally equal to x (like a nickname or alias). in long form, it'd be "y is equal to x, which is equal to 1, therefore y is equal to 1" as opposed to "y is x". does that make sense?

You're generally free from thinking that way in functional languages. You care about values not how they are represented. Basically I could do:

code:
x = [1,2,3,4]
y = x
x = append([1,2], [3,4])
x = y
and have it work fine. In the case of x = append([1,2], [3,4]) the program could determine that the result of append([1,2], [3,4]) is equivalent to x because it compares equal.

It could also use the fact that x and y both have the same pointer to the same data structure when executing x = y so that (given you're immutable) you can stop comparing further and say the expression worked fine.

It's just an implementation detail how you deal with the comparison, but we're dealing with values from the user's perspective here.

Pollyanna posted:

i don't quite see either of those in your example, cause it kinda ends up being a mix of the two. i had envisioned either an entirely new tree (i.e. a copy of all nodes rather than directly affected nodes) or the old tree with an e node attached to f. instead, it looks like it's trying to conserve energy or something by doing the bare minimum it needs to change. meaning, it creates new stuff for what changes, but what doesn't change already exists somewhere in memory, so it just points back to that.

is that correct?

You could do it with two trees entirely and it would work fine by the semantics required. However, it would be inefficient in memory because you'd end up rewriting a shitload of data on every update on a large data structure, and trashing around inefficiently.

Reusing the old tree lets you be more efficient in memory (and processing time) by indeed doing the bare minimum needed. Think of the same diagram if you made 70 updates. It's more efficient to reuse old trees than to have 70 new ones.

MononcQc
May 29, 2007

Bloody posted:

i like how this diagram was designed to look like it was hand-drawn but clearly is not hand-drawn because it actually features like 2 distinct non-circles and font-consistent handwriting

It was originally hand-drawn, then put on a computer. I originally had my own handwriting for most of the drawings, but when I ended up doing the paper version, I (and my girlfriend, who retraced a shitload of illustrations to help me) used a handwritten font to make it more readable to everyone.

Many of these drawings though, when traced back, were using only 2-3 circles because gently caress retracing over all of them. Some are just rotated to give the impression of being handdrawn 100% of the time, but I had more things to do than carefully draw every circle all over again. The same circles are probably used in a bunch of places in the book, but the original ones are drawn by hand.

You can see that the C node is just the D node flipped over, for example.

USSMICHELLEBACHMAN posted:

it looks like it came from here to me but i could be wrong

http://learnyouahaskell.com/

It comes from the printed version of http://learnyousomeerlang.com -- the drawing I posted above only made it in the final print copy of the book and won't be on the website though.

MononcQc
May 29, 2007

Symbolic Butt posted:

pure functional programming is stuff like ml, haskell, erlang, lisp...

I wanted to comment on this one thing here.

"Pure" functional programming is a specific type of functional programming, where side-effects are forbidden not just in the data structures, but also in input/output, to name one. The difference is that in a lisp (or Erlang), we don't give a poo poo about side-effects. In fact, Erlang message passing is a side-effect and the entire language relies on it as one of its basic principles.

It means that if I call (some-call x y) in Scheme and get a 2 back, I don't have a guarantee that some-call won't do poo poo like logging, writing to disk, or uploading my SSN without me knowing, every time I call it.

In a pure language (and not all pure languages are functional -- Mercury is a pure logic language), this kind of side-effecty operation is forbidden unless it's in the right context.

In Haskell, that special context is a monad. The special context you use can impose restrictions on how you can do or call your side-effects.

For example, you could say that all side-effecting functions can call pure functions, but not the opposite. In that way, you let your compiler be free to do all the optimizations it wants on the pure parts of the programs: caching/memoizing, inlining, automatic parallelism, make it lazy, etc. but forbid it to play with the flow of the impure program.

This tends to change the way programmers in these language think about software in major ways, and the gymnastic of forcing your side-effecting operations to all be explicitly marked as such can both be extremely frustrating when you're not used to it, and sane (and possibly safer) when you get to intuitively separate pure from impure code.

MononcQc
May 29, 2007

Pollyanna posted:

so functional programming has the advantage of being memory efficient? that would mean programs would run faster and take up less ram and such, right?

That really depends on the language. Historically, and 99% of the time, the answer is no, functional programs are not more memory efficient. Mutable languages will either do the same kind of sharing, or will just update poo poo directly in memory in a destructive manner so that there is no sensible overhead to modifying existing data structures.

What that tradeoff does, however, is force the programmer to be more disciplined about how they hold outdated references to some data structures (you thought A was in there but it's gone now!), and thinking of all the ideas of references vs. values and whatnot. You don't really care about this in functional programming most of the time.

Some languages are formal enough in how they're designed that you can do an analysis of the data flow of some data structure and figure out that "you know what, it wouldn't hurt anybody if this one operation here was destructive" and you do it. In these cases, when you play in that flow, you can get similar memory efficiency to imperative or OO (or just generally destructive) languages. In practice, this rarely happens, although I don't have extensive experience with such languages.

There's also a special kind of types (Rust uses them iirc) where you can say "it's fine, I'm usually functional, but in this case, I want to go destructive". What these types will do is let you use the language as before, but when you do some poo poo as:

code:
Old = T,
New = insert(e, Old)
print(Old)
The compiler will tell you that you can't reuse Old in print(Old) after it has been update as New. Basically, these type systems will let the compiler enforce a thing where you write programs as if they were immutable, but will warn you and yell at you when you reuse older values.

Because you added that constraint to your language, the language is now free to do destructive operations on the data structures while being 100% safe on data access from older references.

Few languages use that kind of type system, but it's kind of neat to think about.


PS: there are cases where functional languages will use less memory than OO or imperative ones, but that will usually be the result of different things and optimizations being available to the compiler or the runtime to obtain similar objectives, and usually not a direct result of the fact that the language is immutable.


E: the types I mention in this post are Uniqueness types or more generally linear type systems

MononcQc fucked around with this message at 14:28 on Sep 26, 2013

MononcQc
May 29, 2007

coffeetable posted:

theoryspergin': only true on balanced trees. trees in general it can be O(n) b/c their height can be O(n)

True. Most key/value data structures in functional programming are based on trees of different branching factors (because that's often pretty much the best you can do in many cases without breaking immutability) and will use balanced trees because otherwise the performance will turn to poo poo. I tend to forget that non-balanced trees are still a thing that is useful sometimes :toot:

We butthurt functional programmers will have different ways to think about things so we think we're super efficient though, so we get excited about amortized performances in pure data structures instead.

MononcQc
May 29, 2007

if they ask it as a way to "prove" you know the language you'll be working in and you don't have code available for them for some reason and/or you weren't working in it lately, it might be acceptable I guess, assuming you understand the basic lines of mergesort.

MononcQc
May 29, 2007

use awk for text manipulation :getin:

MononcQc
May 29, 2007

if you're dealing with logs and are not using awk you need to learn awk


(unless you have something sweet like splunk going on)

MononcQc
May 29, 2007

fritz posted:

is there any reason to use awk instead of perl

i remember back when i started in the perl4 days one of its big selling points was that it was an awk- and sed-killer and thats still all i use it for, all " perl -pi.back -e 's/buttz/butts/g;' "

Awk is fast as hell and so simple it takes literally 15-30 minutes to learn the basics and get going if you have the right tutorial.

I have parsed crash dumps before to do some simple analytics using awk and it was fairly sweet and straightforward:

code:
# Parse Erlang Crash Dumps and correlate mailbox size to the currently running
# function.
#
# Once in the procs section of the dump, all processes are displayed with
# =proc:<0.M.N> followed by a list of their attributes, which include the
# message queue length and the program counter (what code is currently
# executing).
BEGIN {
    threshold = 10000 # mailbox size
    procs = 0 # are we in the =procs entries?
    print "MESSAGE QUEUE LENGTH: CURRENT FUNCTION"
    print "======================================"
}

# Only bother with the =proc: entries. Anything else is useless.
procs == 0 && /^=proc/ { procs = 1 } # entering the =procs entries
procs == 1 && /^=/ && !/^=proc/ { exit 0 } # we're done


# Message queue length: 1210
# 1       2     3       4
/^Message queue length: / && $4 >= threshold { flag=1; ct=$4 }
/^Message queue length: / && $4 <  threshold { flag=0 }

# Program counter: 0x00007f5fb8cb2238 (io:wait_io_mon_reply/2 + 56)
# 1       2        3                  4                       5 6
flag == 1 && /^Program counter: / { print ct ":", substr($4,2) }
The format is literally:

REGEX AND/OR BOOLEAN { THINGS TO DO IF IT MATCHES }

Every line goes down every clause to be possibly matched, and you have special BEGIN and END clauses that get run once at the beginning and at the end respectively. The REGEX AND/OR BOOLEAN part uses C syntax to do the matching, and supports one or more regex, and works by line.

Then you have a few special variables that can be used:

  • A line is $0
  • Every field of the line is $1, $2, $3, $4, ... $N, where the separator is defined by the variable FS -- the comments in the snippet above show this usage
  • FS is the field-separator, as I said. It can be set per clause, globally, or whatever, depending on when you use the $N variables.
  • OFS is the output field-separator, so that if you do OFS=":"; print $1, $2, you're separating all the values with a colon.
  • NF tells you how many fields there are in a line
  • NR is the current line number
  • RS is the record separator and can be changed if you don't want newlines, similarly for ORS for the output

Each variable is otherwise global in scope, doesn't need initialization, and will act both as string and integers if they can (what is lovely in PHP and JS, but kind of useful for logs). There are also arrays (with trick arrays to multidimensional). Comments start with a #.

The script above would be run by calling:
code:
$ awk -f queue_fun.awk $PATH_TO_DUMP
MESSAGE QUEUE LENGTH: CURRENT FUNCTION
======================================
10641: io:wait_io_mon_reply/2
12646: io:wait_io_mon_reply/2
32991: io:wait_io_mon_reply/2
2183837: io:wait_io_mon_reply/2
730790: io:wait_io_mon_reply/2
...
10412: io:wait_io_mon_reply/2
2554519: some_server:handle_info/3
12443: io:wait_io_mon_reply/2
168785: io:wait_io_mon_reply/2
26314: io:wait_io_mon_reply/2
It's stupidly fast to get something going to parse log files. The one above showed that blocking IO would back memory up and kill nodes.

MononcQc fucked around with this message at 19:28 on Oct 23, 2013

MononcQc
May 29, 2007

I'm too enthusiastic about my one-off awk scripts to leave!!

MononcQc
May 29, 2007

Notorious b.s.d. posted:

there is absolutely no reason to use awk instead of perl. none.

anyone who tells you to use awk either hasn't learned anything new in 20 years, doesn't know perl, or most probably, both. i'm going to give mononqc the benefit of the doubt and assume he's in the "doesn't know perl" category.

Don't know Perl, only used it in some homework to do conway's game of life and then never touched it again. Again Awk takes 15 minutes to learn (my post covers a huge part of the basics on its own). I'm also interested in comparing the speed of both, because when parsing 3-4GB files, a good speedup is worth the 15 minutes investment.

MononcQc
May 29, 2007

PrBacterio posted:

does awk use "extended" or regular (hah!) regexes?
because if it uses just plain old regular expressions, thats probably where the speedup comes from

http://www.math.utah.edu/docs/info/gawk_5.html#SEC28 seems to say it supports both POSIX and extended 'unix stuff', so probably not PCRE. I guess that's where the speedup is, yeah.

MononcQc
May 29, 2007

Deacon of Delicious posted:

for a discussion about parsing you aren't doing it very well

the 15 minute investment isn't for every single time you use awk, it's learning awk the one time and then you potentially save time with each file you parse with awk in the future

Exactly this.

MononcQc
May 29, 2007

yeah but perl is a p-lang

MononcQc
May 29, 2007

I'm just surprised Notorious b.s.d. isn't telling people to do it in Java or something

MononcQc
May 29, 2007

URIs and file paths would totally benefit by not being flattened in a string and instead be some kind of actual data structure :v:

MononcQc
May 29, 2007

Notorious b.s.d. posted:

common lisp's native file i/o is like this. it's really unpleasant. they were trying to abstract out the implementation details of mainframe/lispM/unix file io and ouch ouch ouch ouch ouch

I don't think it's nearly as bad for OS paths, but things like 'joining directory paths' and poo poo should be doable with a given function/method that handles it in a native way so all you have to worry about is providing individual directory names and poo poo, and not get mistery bugs when porting to other platforms.

For URIs, you're just asking for trouble if you don't do it.

MononcQc
May 29, 2007

who escapes forward slashes outside of people using it as a regex delimiter and JSON libraries?

Adbot
ADBOT LOVES YOU

MononcQc
May 29, 2007

Morkai posted:

to be perfectly frank, i would much prefer if we didnt have a bunch of plangers and the like out there "architecting" and "designing" and "developing", because they dont have a strong enough background in fundamentals to know when and why to do needful things. i say this as a hobby programmer/hacker for 15+ years who turned my hobby into a career. i am not a cs grad, and i couldnt do trig to save my life. but i know what it means to use generics and interfaces and abstracts, and i write business software not novel algos.

The more it goes, the more I feel that making assumptions about what the one true way or methodology, language, or paradigm should be, is all garbage.

Programs and software solutions can be CPU, IO, or Memory bound at the simplest levels, and that already impacts the poo poo you have, but then you have additional constraints for budget, development time, running time, and general ideas about capacity, requirements for tests, maintainability, safety and what have you that all compound into these decisions, while also adding the problem domain to that stack.

There's a shitload of cases where p-lang like solutions are fully appropriate given the constraints and priorities, no matter what angry assholes online may think. The opposite is also pretty much true, where Java users can be seen both as morons or reasonable people.

But it's fun for devs of all kind to think "well the kind of programming I do is certainly representative of what the state of the world is and by golly your solution doesn't fit what I usually do! you're probably an idiot!" and get a little self-indulgent feeling of superiority, so I don't expect it to change any time soon.

  • Locked thread