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.
 
  • Post
  • Reply
Jewel
May 2, 2009

FrantzX posted:

C# code:
public struct Indexed<T>
{
	public Indexed(Int32 index, T item)
	{
		Index = index;
		Item = item;
	}

	public readonly Int32 Index;

	public readonly T Item;
}

public static class Extensions
{
	static IEnumerable<Indexed<T>> Indexed<T>(this IEnumerable<T> sequence, Int32 startindex = 0)
	{
		Int32 index = startindex;
		foreach (T obj in sequence) yield return new Indexed<T>(index++, obj);
	}
}
LINQ & extensions method are some the best features I have ever seen in a language.

Ah! C# does have yield! I was curious if it did or not because it seems like the kind of language that would. Cool.

Adbot
ADBOT LOVES YOU

b0lt
Apr 29, 2005

FrantzX posted:

C# code:
public struct Indexed<T>
{
	public Indexed(Int32 index, T item)
	{
		Index = index;
		Item = item;
	}

	public readonly Int32 Index;

	public readonly T Item;
}

public static class Extensions
{
	static IEnumerable<Indexed<T>> Indexed<T>(this IEnumerable<T> sequence, Int32 startindex = 0)
	{
		Int32 index = startindex;
		foreach (T obj in sequence) yield return new Indexed<T>(index++, obj);
	}
}
LINQ & extensions method are some the best features I have ever seen in a language.

code:
implicit class Extension[T](val self: Iterable[T]) {
    def indexed = for ((index, item) <- Stream.from(0) zip self) yield (index, item)
}

ToxicFrog
Apr 26, 2008


Jewel posted:

So technically it's exactly the same as what you do in every other language. What other languages have a feature like "yield", also? I never really noticed it in anything else, or if I did I forgot.

Lua does, as part of coroutine support:

code:
function enumerate(seq)
  return coroutine.wrap(function()
    for index,item in ipairs(seq) do
      coroutine.yield(index, item)
    end
  end)
end

Freakus
Oct 21, 2000

Jewel posted:

Python has that :getin:
Go has that too, e.g.:

code:
for index, row := range rows {
}

for index := range rows {
}

for _, row := range rows {
}

Sedro
Dec 31, 2008

b0lt posted:

code:
implicit class Extension[T](val self: Iterable[T]) {
    def indexed = for ((index, item) <- Stream.from(0) zip self) yield (index, item)
}
AKA zipWithIndex

You can replace the Indexed<T> with Tuple<int, T> but C# doesn't have language support for tuples or pattern matching
C# code:
foreach (var tuple in iterable.Indexed())
{
    var i = tuple.Item1;
    var item = tuple.Item2;
    ....
}
:barf:

fritz
Jul 26, 2003

Opinion Haver posted:

What are these strange 'for loops' of which you speak?

1. readable

Gul Banana
Nov 28, 2003

FrantzX posted:

C# code:
public struct Indexed<T>
{
	public Indexed(Int32 index, T item)
	{
		Index = index;
		Item = item;
	}

	public readonly Int32 Index;

	public readonly T Item;
}

public static class Extensions
{
	static IEnumerable<Indexed<T>> Indexed<T>(this IEnumerable<T> sequence, Int32 startindex = 0)
	{
		Int32 index = startindex;
		foreach (T obj in sequence) yield return new Indexed<T>(index++, obj);
	}
}
LINQ & extensions method are some the best features I have ever seen in a language.
they're better than you think: LINQ already has an overload of Select which provides an index.

Freakus
Oct 21, 2000

fritz posted:

1. readable
I don't know if it can work, but I've always thought programming languages would be more readable if functions came after their parameters, rather than the current method where it's before. Then I wouldn't have to read right to left as often. E.g.:
code:
([0..] ["foo", "bar", "baz"] zip) (\(i, word) -> (i show ++ " " ++ word) putStrLn) mapM_
Maybe I'm crazy though.

Sockser
Jun 28, 2007

This world only remembers the results!




Why would you read the parameters before the function name, though?

Scaevolus
Apr 16, 2007

Freakus posted:

I don't know if it can work, but I've always thought programming languages would be more readable if functions came after their parameters, rather than the current method where it's before. Then I wouldn't have to read right to left as often. E.g.:
code:
([0..] ["foo", "bar", "baz"] zip) (\(i, word) -> (i show ++ " " ++ word) putStrLn) mapM_
Maybe I'm crazy though.

Have you seen the wonders of Forth?

het
Nov 14, 2002

A dark black past
is my most valued
possession

Freakus posted:

I don't know if it can work, but I've always thought programming languages would be more readable if functions came after their parameters, rather than the current method where it's before. Then I wouldn't have to read right to left as often. E.g.:
code:
([0..] ["foo", "bar", "baz"] zip) (\(i, word) -> (i show ++ " " ++ word) putStrLn) mapM_
Maybe I'm crazy though.
I think way more people would be reading right to left in this scenario. That doesn't mean it doesn't make more sense for you, but it's definitely jarring/counter-intuitive for me. I mean, I think of it as being influenced by one's native spoken/written language (and maybe that's unfounded), but with English (and most Western languages to my knowledge) being subject-verb-object, having the action at the end makes it far more difficult for me to parse. Maybe that's why OOP caught on as a paradigm, as imperative languages sort of have the implicit subject of the interpreter/computer, whereas object orientation supplies an explicit subject with the object, and the method being the verb.

Athas
Aug 6, 2007

fuck that joker

Opinion Haver posted:

What are these strange 'for loops' of which you speak?

code:
> mapM_ (\(i, word) -> putStrLn (show i ++ " " ++ word)) (zip [0..] ["foo", "bar", "baz"])
0 foo
1 bar
2 baz

That is a coding horror (or at least a little goosebumpy). Use forM_ and indentation!

code:
forM_ (zip [0..] ["foo", "bar", "baz"]) $ \(i, word) ->
  putStrLn (show i ++ " " ++ word)
See, much better.

gonadic io
Feb 16, 2011

>>=
code:
zipWithM_ printIxWord [0..] ["foo", "bar", "baz"]
    where printIxWord i word = putStrLn (show i ++ " " ++ word)
e: or best yet
code:
import Control.Lens.Indexed
import Text.Printf

imapM_ (printf "%d %s\n") ["foo", "bar", "baz"]
lens can do some craazy poo poo

gonadic io fucked around with this message at 14:36 on Dec 21, 2013

weird
Jun 4, 2012

by zen death robot
code:
> (iter (for word in-sequence '("foo" "bar" "baz") with-index i)
        (format t "~a ~a~%" i word))
0 foo
1 bar
2 baz

Deus Rex
Mar 5, 2005

AlsoD posted:

code:
zipWithM_ printIxWord [0..] ["foo", "bar", "baz"]
    where printIxWord i word = putStrLn (show i ++ " " ++ word)
e: or best yet
code:
import Control.Lens.Indexed
import Text.Printf

imapM_ (printf "%d %s\n") ["foo", "bar", "baz"]
lens can do some craazy poo poo

Wow. So you can iterate over an iterable and also their indexes and perform some effectful computation on them (in other words, print them). Crazy poo poo indeed, my man. :monocle:

Internet Janitor
May 17, 2008

"That isn't the appropriate trash receptacle."

Scaevolus posted:

Have you seen the wonders of Forth?

In particular if you guys are interested in manipulating lazy sequences and creating functional pipelines you might find this post worth reading.

MononcQc
May 29, 2007

hint: if your functional language supports a fold idiom you're able to provide that mechanism in one line, no matter what:

code:
foreach_i(F, List) -> 
    lists:foldl(fun(Term, I) -> F(I,Term), I+1 end, 0, List).
code:
(define (foreach-i f lst)
    (fold (lambda (term i) (begin (f i term) (+ 1 i))) 0 lst))
And can then be called as foreach_i(fun(Index, Term) -> WHATEVER end, LIST)
or (foreach-i (lambda (i term) WHATEVER) LIST)

whether someone decided to add this to the standard library or not decides whether you can feel smug in the last 2 pages I guess.

Blinkz0rz
May 27, 2001

MY CONTEMPT FOR MY OWN EMPLOYEES IS ONLY MATCHED BY MY LOVE FOR TOM BRADY'S SWEATY MAGA BALLS
The sad thing is that this is literally the only worthwhile thing about PHP

code:

foreach($things as $i => $thing) {
    echo $i;
    echo $thing;
}

ToxicFrog
Apr 26, 2008


Freakus posted:

I don't know if it can work, but I've always thought programming languages would be more readable if functions came after their parameters, rather than the current method where it's before. Then I wouldn't have to read right to left as often. E.g.:
code:
([0..] ["foo", "bar", "baz"] zip) (\(i, word) -> (i show ++ " " ++ word) putStrLn) mapM_
Maybe I'm crazy though.

Clojure has the -> macro (and its relatives ->> some-> some->>), which does exactly this. Rather than writing h(g(f(x))) (Java) or (h (g (f x))) (Clojure), you can write (-> x f g h), which is, a lot of the time, much more readable.

The best part is that it works on method calls too, so something that would be expressed in Java as h(f(x).g()) and thus needs to be read in both directions at once becomes (-> x f .g h).

The some variants check for nil on each stage of the pipeline and return nil immediately, which means you can write the equivalent of h(g(f(x))).toString() as (some-> x f g h .toString) and if any of those functions or methods returns nil, the whole expression will return nil rather than throwing NullPointerException.

weird
Jun 4, 2012

by zen death robot

ToxicFrog posted:

Clojure has the -> macro (and its relatives ->> some-> some->>), which does exactly this. Rather than writing h(g(f(x))) (Java) or (h (g (f x))) (Clojure), you can write (-> x f g h), which is, a lot of the time, much more readable.

I read your post and wondered why it was a macro, and the reason is a nice thing you didn't mention: if the forms after x are lists then it puts x as the first argument, so eg (-> 1 (list 2 3)) expands to (list 1 2 3). That's really convenient.

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.
The ML family usually has an operator like |> (or you can easily write it) that lets you make something that looks like a pipeline:
code:
(f x) |> g |> h
Each result gets fed as an argument to the next. However, I find this kind of sugar cute but worthless. If an expression is too ugly, just use some intermediate variables. I guess this goes back to the "naming things is hard, so let's not do it" thing, though.

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

Mustach posted:

The ML family usually has an operator like |> (or you can easily write it) that lets you make something that looks like a pipeline:
code:
(f x) |> g |> h
Each result gets fed as an argument to the next. However, I find this kind of sugar cute but worthless. If an expression is too ugly, just use some intermediate variables. I guess this goes back to the "naming things is hard, so let's not do it" thing, though.

I haven't used those languages so I can't say for sure, but I don't agree that throwing more code in always makes something more readable. I could see this sort of thing being very readable if you were, say, transforming a point:

code:
-> x (rotate 45) (invert) (scale 6)
Using intermediate variables here would be a lot less readable to me

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.
Oftentimes, you don't even need new variables. In that case I would probably rotate x, invert x, and scale x in three steps.

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

AlsoD posted:

This all seems like stockholm syndrome for languages where anything could implicitly and silently be null.

It depends on how comfortable you are with nullable database columns, where in a result set, any or all of the values could be null, no big deal.

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

Mustach posted:

Oftentimes, you don't even need new variables. In that case I would probably rotate x, invert x, and scale x in three steps.

That works if the functions mutate x, but if they return a new value then you have to do x = rotate(x, 45) etc. or x = scale(invert(rotate(x, 45)), 6). They're both less readable (again, IMO), the first just because it's ugly and the second because now you have to read backwards.

Sometimes I like terseness because it makes it easier to chunk things mentally. If you read that single line you can easily see what's happening at a glance, but when you break it up it takes a bit longer to figure out what's happening because it's not immediately clear that the code forms a conceptual unit until you read it all. It's only a slight difference of course but I find it helps. It's just important to distinguish between terseness that makes things clearer and terseness that obscures.

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.
v:)v I find x = rotate(x,45) very nice. C'est la vie.

jony neuemonic
Nov 13, 2009


PHP has a shorthand version of the ternary operator for that, so you can do:

PHP code:
$foo = $bar ?: $baz
Of course, given PHP's weird ternary implementation and type coercion I'm sure there's some lurking horror. Still, it's convenient for default values and hasn't bit me (yet).

Opinion Haver
Apr 9, 2007

Deus Rex posted:

Wow. So you can iterate over an iterable and also their indexes and perform some effectful computation on them (in other words, print them). Crazy poo poo indeed, my man. :monocle:

You can also nest the iteration arbitrarily deeply or even have it write the traversal for you!

code:
> let x = [Just ["Hello"], Nothing, Just[", ", "world!"]]
> x^!traverse.traverse.traverse.traverse.act putChar
Hello, world
> x^!biplate.filtered (even . ord).act putChar
Hll, rld
But, in keeping with the theme of the thread, the type signatures can be... impenetrable (although the first line of this error does give a pretty good hint that you're not traversing enough):
code:
> x^!traverse.traverse.traverse.filtered (even . ord).act putChar

<interactive>:81:31:
    Couldn't match type `Char' with `[Char]'
    Expected type: (Char
                    -> Control.Lens.Internal.Action.Effect IO () Char)
                   -> [Char] -> Control.Lens.Internal.Action.Effect IO () Char
      Actual type: Overloaded'
                     (->) (Control.Lens.Internal.Action.Effect IO ()) Char Char
    In the return type of a call of `filtered'
    In the first argument of `(.)', namely `filtered (even . ord)'
    In the second argument of `(.)', namely
      `filtered (even . ord) . act putChar'

Houston Rockets
Apr 15, 2006

https://plus.google.com/+GregorJRothfuss/posts/HnMp8JTurF2

quote:

Turns out that 18 years ago, PHP had about 100 functions. The function names got put in a hash map. The hash function chosen? Strlen. Thus, the function names were chosen so the hash collisions would be minimized (by creating a uniform distribution of function name length). Which means the origin of all those insane and inconsistent names in PHP is even worse than I'd always thought.

I am literally blown away. I can barely conceive of a more mind-shatteringly idiotic thing.

Escape Goat
Jan 30, 2009


Mother of god...

I'm so thankful this holiday for not having to use PHP.

Pollyanna
Mar 5, 2005

Milk's on them.


Pee pee doo doo it is a bad language.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Does anybody here notice a culture change when working with engineers in Mexico? I'm finding them to have a very strong attitude that their poo poo doesn't stink and my stuff is terrible, even without them having heard of it or looked at it. It's kind of hard to support a team over there when they're hostile to you from the get-go. I kind of wonder if I just need to throw on some macho and try not to be too modest. It's kind of a lovely question to be asking, but from seeing some of cultural factors towards working with code with Indians, to have full-duplex conversations* with Israelis, I wonder if there's just a cultural thing here.

*At least the ones I run into just start talking over you like a bulldozer every time you open your mouth. After watching them talk to each other for awhile, I just figured out they all just talk at the same time to each other (full duplex) instead of taking turns (half-duplex). I still think it's rude but I know to just keep going, but I haven't quite figured out how to dart back and forth between what they're saying and what I'm trying to say. The world is a strange place.

Pollyanna
Mar 5, 2005

Milk's on them.


It's definitely the machismo. Are they the contractors or are you the contractor? If it's the former, then you have precedence over them. Dickheads like those don't respond to anything except acting like you have the bigger set of balls.

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

Pollyanna posted:

It's definitely the machismo. Are they the contractors or are you the contractor? If it's the former, then you have precedence over them. Dickheads like those don't respond to anything except acting like you have the bigger set of balls.

Why are you posting like you know what you're talking about?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
Practise what you preach, I guess.

Maluco Marinero
Jan 18, 2001

Damn that's a
fine elephant.

Bruegels Fuckbooks posted:

Why are you posting like you know what you're talking about?

Yep, you're not terrible, but theres many conversations where you'd be better of listening and learning.

xtal
Jan 9, 2011

by Fluffdaddy

Rocko Bonaparte posted:

Does anybody here notice a culture change when working with engineers in Mexico? I'm finding them to have a very strong attitude that their poo poo doesn't stink and my stuff is terrible, even without them having heard of it or looked at it. It's kind of hard to support a team over there when they're hostile to you from the get-go. I kind of wonder if I just need to throw on some macho and try not to be too modest. It's kind of a lovely question to be asking, but from seeing some of cultural factors towards working with code with Indians, to have full-duplex conversations* with Israelis, I wonder if there's just a cultural thing here.

*At least the ones I run into just start talking over you like a bulldozer every time you open your mouth. After watching them talk to each other for awhile, I just figured out they all just talk at the same time to each other (full duplex) instead of taking turns (half-duplex). I still think it's rude but I know to just keep going, but I haven't quite figured out how to dart back and forth between what they're saying and what I'm trying to say. The world is a strange place.

http://xkcd.com/385/

Gazpacho
Jun 18, 2004

by Fluffdaddy
Slippery Tilde
Oh god not this, argue about type coercion some more.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Well I had a feeling I'd get negative responses so I'll grab the shovel and try to dig some more; whether or not I dig myself out or dig myself deeper is something we'll figure out. Generally where I work, I am not always certain of where somebody is when I'm first corresponding with them. I can go out out of my way and find their geographic location, although I usually don't. And in all cases, culture does take second place to management, and this organization's manager is pretty shady. I'm pretty sure he's hostile to us since he wanted to do all the work himself and build himself up a whole bunch. If we're talking about code quality, the code I've seen of theirs is indeed crap, but it follows a specific model that one regular old US white guy likes to do. So just from what that guy has done and proliferated, I have to be real humble about Americans.

My angle was that when interacting with different cultures I have had to take different tact some times, depending on the circumstances. If I'm working with Indians working in India, I have to find clever ways to figure out what they don't know, because they try to cover it up very well. It's frustrating when it's domain specific knowledge they wouldn't know in the first place, like me trying to show them how to use something I made for them. So I have found prompts and ways to ask about their situation, and how what I'm explaining might affect it, to make sure they understand. Otherwise, they just don't do anything. The Israeli tact is that when I'm on the phone with them or in person, I just keep talking if I have to make a point, and not get butt-hurt about being interrupted. So with this group in Mexico I'm trying to figure out if I need to find a tact with them to try to subdue what I think is hostility, or if their manager is just a dick and it's contagious--it wouldn't be the first time.

Adbot
ADBOT LOVES YOU

ninjeff
Jan 19, 2004

Gazpacho posted:

Oh god not this, argue about type coercion some more.

Somebody post about a language feature so we can all post about how to twist our favourite language into doing it.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply