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
rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Volte posted:

So what's the deal with Swift's weird generic limitations?

Mostly just implementation restrictions that we plan to lift sooner rather than later.

Volte posted:

I already can't use algebraic datatypes because I can't do something like:
code:
enum Expr<T> {
  case Const(T)
  case Var(Variable<T>)
  case BinOp<U, V>(Op<U, V, T>) // can't introduce U,V
  // ...
}

Existential type erasure in ADTs is a rather advanced feature that most functional languages don't have. We'd like to have full GADTs eventually, and I made a point of ensuring that the case declaration syntax would support it, but they do add a lot of complexity to the type system, and we didn't consider it to be high-priority for the first release.

Volte posted:

(actually, enums with generics in their payloads seem to cause the compiler to segfault anyway)

This isn't, like, unconditionally true; please file bugs with the test case you've got. But anyway, yes, right now we don't support recursive enums, so you're going to have to use classes.

Volte posted:

But in Swift for some reason a class derived from a generic must also be generic.

Yes. It's just a dumb implementation restriction.

Adbot
ADBOT LOVES YOU

Doh004
Apr 22, 2007

Mmmmm Donuts...
I do iOS development for my job and I figured I should start learning how to use Swift, so I made TicTacToe. If anyone is bored could you please give me some pointers? I definitely found myself doing a lot of stuff incorrectly because I'm so used to Obj-C so I know I didn't do things in the proper "Swift" way (if that even exists?).

https://github.com/BayPhillips/TicTacToe

Thank you!

brap
Aug 23, 2004

Grimey Drawer
Wow, Xcode's error messages for Swift are frustrating. I hope they are improved eventually.

eschaton
Mar 7, 2007

Don't you just hate when you wind up in a store with people who are in a socioeconomic class that is pretty obviously about two levels lower than your own?

Doh004 posted:

I do iOS development for my job and I figured I should start learning how to use Swift, so I made TicTacToe. If anyone is bored could you please give me some pointers? I definitely found myself doing a lot of stuff incorrectly because I'm so used to Obj-C so I know I didn't do things in the proper "Swift" way (if that even exists?).

https://github.com/BayPhillips/TicTacToe

Thank you!

Where are your tests? :colbert:

You should follow similar naming conventions to Objective-C with Swift, i.e. start properties and method names with a lower-case letter, make the name of a method read as a sentence, etc.

For example, this:

code:

    func PlayersCornerPieces(player: Player) -> [GamePiece]

should be more like this:

code:

    func cornerPiecesForPlayer(player: Player) -> [GamePiece]

similar to how it would be in Objective-C.

The separate model classes should also be in separate files, rather than all in one, for stylistic reasons. More practically they have methods that should really be properties, even computed properties like Player.displayName (for which I did like your use of interpolation, that's what I'd have done too). Also, the type for something like that can be just String, not String!, since you probably don't need to introduce an implicitly unwrapped optional for something like that.

eschaton fucked around with this message at 05:09 on Sep 22, 2014

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

fleshweasel posted:

Wow, Xcode's error messages for Swift are frustrating. I hope they are improved eventually.

Yeah, there's a huge amount of quality work to be done on diagnostics. None of us are happy with how things stand now.

If you see terrible diagnostics and have specific suggestions for how they could have been better, that's definitely worth filing bugs about, especially for things that aren't just expression type-checking. Quality work like this tends to be a long slog of adding minor improvements, and having a bunch of little things spelled out as individual bugs really does help. (Plus it gives us an idea of what people are hitting most, and thus what to prioritize improving.)

Doh004
Apr 22, 2007

Mmmmm Donuts...

eschaton posted:

Where are your tests? :colbert:

YOLO

eschaton posted:

You should follow similar naming conventions to Objective-C with Swift, i.e. start properties and method names with a lower-case letter, make the name of a method read as a sentence, etc.

For example, this:

code:
    func PlayersCornerPieces(player: Player) -> [GamePiece]
should be more like this:

code:
    func cornerPiecesForPlayer(player: Player) -> [GamePiece]
similar to how it would be in Objective-C.

The separate model classes should also be in separate files, rather than all in one, for stylistic reasons. More practically they have methods that should really be properties, even computed properties like Player.displayName (for which I did like your use of interpolation, that's what I'd have done too). Also, the type for something like that can be just String, not String!, since you probably don't need to introduce an implicitly unwrapped optional for something like that.

I don't know why I ended up naming a lot of my properties and functions like that. For some reason I started combining C#/Java into it all. But do we really need to stay with the old naming convention? I'm used to it but :saddowns:. Also, howcome you can't right click -> refactor -> rename swift files?

And yeah I need to move those classes into their own files. While I was making it I just kept it in one file so I could see it all while working on it. General code cleanup would be great.

brap
Aug 23, 2004

Grimey Drawer
I noticed explicitly in release notes that refactoring is not yet supported. Hope that won't be too long to receive. Otherwise...I guess I'll be Find and Replacing, or just changing a property name and going through the error list pasting in the new name.

Question about conventions: what do people tend to call a class designed to deserialize objects from a JSON API into strongly typed objects? Do people say "service adaptor" in the iOS world? Sorry if this is a dumb question.

brap fucked around with this message at 17:58 on Sep 22, 2014

Doctor w-rw-rw-
Jun 24, 2008

fleshweasel posted:

Question about conventions: what do people tend to call a class designed to deserialize objects from a JSON API into strongly typed objects? Do people say "service adaptor" in the iOS world? Sorry if this is a dumb question.

I'd probably call it an unmarshaller or deserializer.

Doh004
Apr 22, 2007

Mmmmm Donuts...

This

brap
Aug 23, 2004

Grimey Drawer
More JSON difficulty here. I have a JSON object that I successfully converted to Array<Dictionary<String, AnyObject>>. When I say something like:

code:
self.aStringProperty = json["key"]
I get a complaint that (String, AnyObject) is not convertible to String. I would at LEAST expect that it say AnyObject is not convertible to String. Why is it thinking that the subscript notation is giving the whole key/value pair?

Glimm
Jul 27, 2005

Time is only gonna pass you by

fleshweasel posted:

More JSON difficulty here. I have a JSON object that I successfully converted to Array<Dictionary<String, AnyObject>>. When I say something like:

code:
self.aStringProperty = json["key"]
I get a complaint that (String, AnyObject) is not convertible to String. I would at LEAST expect that it say AnyObject is not convertible to String. Why is it thinking that the subscript notation is giving the whole key/value pair?

It looks to me like json is an array there? Do you mean json[0]["key"]?

dizzywhip
Dec 23, 2005

fleshweasel posted:

More JSON difficulty here. I have a JSON object that I successfully converted to Array<Dictionary<String, AnyObject>>. When I say something like:

code:
self.aStringProperty = json["key"]
I get a complaint that (String, AnyObject) is not convertible to String. I would at LEAST expect that it say AnyObject is not convertible to String. Why is it thinking that the subscript notation is giving the whole key/value pair?

Yeah, you've got an array of dictionaries there. It would probably be more helpful if the compiler complained about the fact that you're subscripting an array with a string instead of an int before it complained about converting a dictionary to a string.

Also, I'd recommend using the array and dictionary type shorthand, it's a lot easier to read: [[String:AnyObject]].

I threw together a little JSON handler that's been working pretty well for me so far. Feel free to use it if you're interested: https://gist.github.com/dizzywhip/046691faa20ef5a1b0db

Volte
Oct 4, 2004

woosh woosh
I'm literally laughing at the Swift standard library right now. I know documentation is sparse so I tried looking at the definitions to figure out how to conform to CollectionType.

code:
protocol CollectionType : _CollectionType, SequenceType {
    subscript (i: Self.Index) -> Self.Generator.Element { get }
}
protocol SequenceType : _Sequence_Type {
    typealias Generator : GeneratorType
    func generate() -> Generator
}
protocol _Sequence_Type : _SequenceType {
    typealias Generator : GeneratorType
    func generate() -> Generator
}
protocol _CollectionType : _SequenceType {
    typealias Index : ForwardIndexType
    var startIndex: Index { get }
    var endIndex: Index { get }
    typealias _Element
    subscript (i: Index) -> _Element { get }
}
protocol _SequenceType {
}
I did not expect this.

lord funk
Feb 16, 2004

How do you write out Swift methods? For example, if I say viewDidLoad() that makes sense. Same with UIImage(named:). But what about UIButton's set image for control state? Is it:

setImage(forState:)
or
setImage(image:forState:)

The documentation uses the Obj-C way of -setImage:forState: which doesn't seem right.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

lord funk posted:

How do you write out Swift methods? For example, if I say viewDidLoad() that makes sense. Same with UIImage(named:). But what about UIButton's set image for control state? Is it:

setImage(forState:)
or
setImage(image:forState:)

The documentation uses the Obj-C way of -setImage:forState: which doesn't seem right.

Xcode's symbol menu thinger does
setImage(_:forState:)
which I'm not sure I like. I would say your first option is unacceptable because it looks like the method takes one parameter when it actually takes two.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Volte posted:

I'm literally laughing at the Swift standard library right now. I know documentation is sparse so I tried looking at the definitions to figure out how to conform to CollectionType.

I really don't remember why he did this. Some bug workaround, I think. I don't know if there's still a reason it needs to be that way.

brap
Aug 23, 2004

Grimey Drawer
Following up about my json question--it's really a dictionary access question. Best I can tell, I'm working with a Dictionary<String, AnyObject>, NOT an Array<Dictionary<String, AnyObject>>.

code:
class BusStop {
    let ID: Int?
    
    init(json: [String: AnyObject]) {
        self.ID = json["ID"]
    }
}
"(String, AnyObject) is not convertible to Int." The error is the same if I add "as Int" at the end.

edit: When I mess with debug print statements, the type of json["ID"] is Optional. The type of json["ID"]! is NSCFNumber. If I change that assignment statement to put the ! after json["ID"] it complains that it's not an optional type!

This code passes diagnostics without complaint:

code:
if let id: AnyObject = json["ID"] {
       self.ID = id as? Int
}
The thing is, I really don't want optionals for this type. I want to assume that every instance will have all of these values and that they'll all be immutable. So I'm finding this process to be kind of a pain in the butt.

edit finally:

For whatever reason, this code works.
code:
self.ID = json["ID"]! as Int
Okay. I'm assuming it will just blow up if the dictionary doesn't have a number under the index "ID". That's fine. Sorry for all the text.

brap fucked around with this message at 02:28 on Sep 25, 2014

Kallikrates
Jul 7, 2002
Pro Lurker
How are people dealing with inter-op and handling unit tests that depend on bridging headers? Far as I can tell I can't change the name of the generated bridging header so for testing Obj-c that imports swift files I'm left with a hacky

code:
// swft -> objc bridge
//test set in test target

#ifdef TEST
#import "Unit-Tests-Swift.h";
#else
#import "MainTarget-Swift.h";
#endif
I can control the name of the other bridging header fine (objc -> swift)

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

fleshweasel posted:

Following up about my json question--it's really a dictionary access question.

Huh. I really thought I replied to this, but apparently I never hit send or something. There are a couple of problems here on our side; both are worth filing as bugs, and I went ahead and filed both for you internally.

The first is that the type-checker is getting lost in the weeds and giving you a terrible diagnostic. Your first attempt really is invalid, but it's because you can't implicitly convert from AnyObject to Int; you have to use a cast. But instead of diagnosing that correctly, it's apparently (1) deciding that the subscript operator you actually want — the one that takes a String and returns an AnyObject? — isn't going to work, (2) trying out a different and less-generally-useful subscript operator, which takes a Dictionary.Index and returns the corresponding entry (i.e. a key/value pair), (3) deciding that that won't work either, and (4) diagnosing based on the second option for no good reason. So that's a type-checker diagnostics bug.

The second is that there's a restriction — which I thought we'd eliminated but apparently not — where a lot of the conversions between AnyObject and the core value types like Int require you to have explicitly imported Foundation in a particular file. Without being able to see NSNumber, we don't know how to do the cast, and so the code doesn't type-check. This is really dumb. When you do import Foundation, self.ID = json["ID"] as Int should work fine, without the !. If it doesn't, it should in the next seed.

You should have better luck using [String: Any] instead of [String: AnyObject].

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
I have a framework and a test bundle for iOS, both entirely Swift. The framework uses a bridging header to import a CocoaPod for internal use. The framework builds fine on its own. The test bundle links against the framework.

At this point, when I build the test bundle, I get an error compiling the framework's bridging header. I can fix the problem by adding the header search path to the test target, but I don't understand why I need to do this. Why does a target linking a framework need to appease the framework's bridging header? The framework doesn't publicly expose any symbols imported in its bridging header, it's purely internal use. The framework's umbrella header is empty. Am I missing something, or is this just a bug?

I get the same issue with an extension target and with an app target, it's not just a test bundle.

brap
Aug 23, 2004

Grimey Drawer
I'm having difficulty getting this extension method working.
code:
extension Array {
    func compareTo<T: Equatable>(other: [T]) -> Bool {
        for (key, value) in enumerate(self) {
            let otherValue = other[key]
            if value != otherValue {
                return false
            }
        }
        return true
    }
}
The error is: Cannot invoke '!=' with an argument list of type (T, T). I thought the point of that <T: Equatable> was to address that.

Glimm
Jul 27, 2005

Time is only gonna pass you by

fleshweasel posted:

I'm having difficulty getting this extension method working.

The error is: Cannot invoke '!=' with an argument list of type (T, T). I thought the point of that <T: Equatable> was to address that.

I think the extension doesn't know that self is an Array<T>, so maybe:

code:
extension Array {
    func compareTo<T: Equatable>(other: [T]) -> Bool {
        for (key, value) in enumerate(self) {
            if let value = value as? T {
                let otherValue: T = other[key]
                if value != otherValue {
                    return false
                }
            } else {
                return false
            }
        }
        return true
    }
}
edit: oh yeah some bounds checking would be good too

Glimm fucked around with this message at 14:34 on Sep 29, 2014

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

fleshweasel posted:

I'm having difficulty getting this extension method working.

That's declaring a new generic argument shadowing the old one (which should probably not be allowed, for exactly this reason), not adding a new constraint to the old one. What you really want is extension Array<T: Equatable>. Unfortunately, that's not yet supported as a feature.

For now, you have to do it with a top-level function.

dizzywhip
Dec 23, 2005

fleshweasel posted:

I'm having difficulty getting this extension method working.
code:
extension Array {
    func compareTo<T: Equatable>(other: [T]) -> Bool {
        for (key, value) in enumerate(self) {
            let otherValue = other[key]
            if value != otherValue {
                return false
            }
        }
        return true
    }
}
The error is: Cannot invoke '!=' with an argument list of type (T, T). I thought the point of that <T: Equatable> was to address that.

I know you didn't ask for this kind of advice, but you probably want to compare the counts of the arrays at the top of the function to make sure they're equal. [1, 2].compareTo([1, 2, 3]) would return true, and [1, 2, 3].compareTo([1, 2]) would crash trying to access an out-of-bounds element in the second array.

brap
Aug 23, 2004

Grimey Drawer
Yeah, should've caught that. Was too focused on the equality business.
probably should be an old school for loop too.

brap fucked around with this message at 06:03 on Sep 29, 2014

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
What's the current story for building a framework that mixes Swift and Objective-C and that depends on some CocoaPods to get its work done? All I can come up with is "go gently caress yourself".

Not even blaming anyone (except CocoaPods and my dumbass self), just wondering if anyone's made something similar-sounding actually work.

Can't wait for the tooling to gear up around Swift. Rolling out a new systems language while barely managing annual OS updates must be ridiculous.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
Using CocoaPods from Swift isn't any more of an issue than any other Obj-C code. The main problematic bit is that all of the Swift files have to be in the final application target (both because CocoaPods can't create framework targets yet and because iOS 7 doesn't support Swift frameworks). The best solution I've come up with for that is to add the Swift source files to preserve_paths in the podspec and tell people to manually add the files to their application target after installing the pod (and prefixing names and not using internal access since your code isn't being built into its own framework).

lord funk
Feb 16, 2004

Is there a particular reason why arrays don't have a removeObject: method like NSArray? Is it a safety thing?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

lord funk posted:

Is there a particular reason why arrays don't have a removeObject: method like NSArray? Is it a safety thing?

Mmm. It's algorithmically inefficient, but that alone isn't necessarily a compelling reason to not have it. Probably the right approach is that we should offer an in-place filter, and you could just do array.removeIf({$0 == object}).

ljw1004
Jan 18, 2005

rum
What do people think of this person's experiences with Swift?

http://swiftopinions.wordpress.com/2014/09/29/to-swift-and-back-again/

Summary: 15kloc project, translated from ObjectiveC to Swift, and major wins were readability of code, non-nullables, immutability and value-types. Had to retreat back to ObjectiveC because Swift compile-time perf was too slow, generics too buggy, and runtime perf was too unpredictable. The language pain points were the picky rules about definite assignment in structs, limits on generics, non-nullables not allowing nice code idioms, and just a generic preference for the python/objectivec/javascript dynamic world.


The complaint that resonates most with me is the picky rules about definite assignment in structs. I much prefer the C# route which says that definite assignment mostly works unless you use virtual calls in your constructor and use them in a stupid way. That puts the pain on the 0.01% of people who abuse the flexibility, rather than the 50% who use the flexibility safely to achieve cleaner code. (Maybe that's an impossible relaxation to achieve with Swift's non-nullable types? Or maybe if is possible if Swift says "this non-nullable type will never be null, unless you've deliberately shot yourself in the foot with stupid virtual stuff in your constructor"?)

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
It really is okay to use implicitly-unwrapped optionals for these complicated dynamic-initialization patterns that don't map over very well to definite static initialization. Using an implicitly-unwrapped optional like that basically is like saying "this value will never be null unless I've accidentally shot myself in the foot with stupid virtual stuff". We don't want to add that to truly non-optional types, because what's the point if they really can be null?

Where are these classes coming from that you need to initialize your superclass before you can start filling in your own fields? I apologize if they're coming from Apple, because in my experience that's never a good class design; it's convenient for about one-and-a-half revisions, and then it starts forcing your code into terrible contortions in order to fit everything around the exact initialization order, and all sorts of secondary crap has to get forced into your constructors for no good reason.

Toady
Jan 12, 2009

There's work to do on Swift, but that article doesn't provide sufficient evidence or examples for some of its assertions, such as

quote:

Syntax improvements will make the Optionals more palatable, but right now their potential to create live crashes and obfuscate the code outweigh their use in making sure that the code is correct.

and

quote:

The contorted if ((self = [super init])) { } return self; is something that makes grown men cry, and is probably the single biggest reason why people use fewer classes in ObjC compared to languages like Java and C++.

brap
Aug 23, 2004

Grimey Drawer
If you use assignment in loop conditions in a high level language, die in a fire please.
Proper handling of optionals is just like proper handling of null in other languages-- check for null before unwrapping it, or use the if let = someOptional syntax. You just don't get silent failure when calling a method on nil in Swift as you do in Objective-C.

dukerson
Dec 28, 2012
So not sure if this is the best place for this, but I haven't been able to find any answers elsewhere:

My Swift port of an existing Obj-C app keeps on getting rejected from the App Store due to crashing. Specifically, the following excerpt from the crash log provided by the App Store:

pre:
Dyld Error Message:
  Library not loaded: @rpath/libswiftCore.dylib
  Referenced from: /private/var/mobile/Containers/Bundle/Application/ED6A7194-EAD0-4FB6-8E81-C4C987E60E08/<AppName>.app/<AppName>
  Reason: no suitable image found.  Did find:
	/private/var/mobile/Containers/Bundle/Application/ED6A7194-EAD0-4FB6-8E81-C4C987E60E08/
<AppName>..app/Frameworks/libswiftCore.dylib: mmap() error 1 at address=0x100168000, size=0x00194000 segment=__TEXT in Segment::map() 
mapping /private/var/mobile/Containers/Bundle/Application/ED6A7194-EAD0-4FB6-8E81-C4C987E60E08/<AppName>.app/Frameworks/libswiftCore.dylib
  Dyld Version: 353.5
I'm unable to reproduce this issue on my end via phone or Simulator (even creating the Archive, submitting it as an Ad Hoc .ipa, and installing it onto my phone works completely fine) -- I'm guessing I'm missing something very dumb? Has anyone run into anything similar? It looks like it's unable to find the swift core libraries, or something similar?

dukerson fucked around with this message at 01:16 on Oct 4, 2014

Glimm
Jul 27, 2005

Time is only gonna pass you by

dukerson posted:

So not sure if this is the best place for this, but I haven't been able to find any answers elsewhere:

My Swift port of an existing Obj-C app keeps on getting rejected from the App Store due to crashing. Specifically, the following excerpt from the crash log provided by the App Store:

pre:
Dyld Error Message:
  Library not loaded: @rpath/libswiftCore.dylib
  Referenced from: /private/var/mobile/Containers/Bundle/Application/ED6A7194-EAD0-4FB6-8E81-C4C987E60E08/<AppName>.app/<AppName>
  Reason: no suitable image found.  Did find:
	/private/var/mobile/Containers/Bundle/Application/ED6A7194-EAD0-4FB6-8E81-C4C987E60E08/
<AppName>..app/Frameworks/libswiftCore.dylib: mmap() error 1 at address=0x100168000, size=0x00194000 segment=__TEXT in Segment::map() 
mapping /private/var/mobile/Containers/Bundle/Application/ED6A7194-EAD0-4FB6-8E81-C4C987E60E08/<AppName>.app/Frameworks/libswiftCore.dylib
  Dyld Version: 353.5
I'm unable to reproduce this issue on my end via phone or Simulator (even creating the Archive, submitting it as an Ad Hoc .ipa, and installing it onto my phone works completely fine) -- I'm guessing I'm missing something very dumb? Has anyone run into anything similar? It looks like it's unable to find the swift core libraries, or something similar?

Might be related to this: https://twitter.com/rustyshelf/status/518205886703996928

Looks like apps recently submitted that use frameworks are crashing on launch.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Glimm posted:

Might be related to this: https://twitter.com/rustyshelf/status/518205886703996928

Looks like apps recently submitted that use frameworks are crashing on launch.

Yeah twitter's lighting up about it. Here's a devforums thread about it, another one is linked somewhere therein. Some are crashing on embedded frameworks, others with the exact error mentioned by dukerson.

Threads don't mention anything helpful, but you're not alone I guess.

lord funk
Feb 16, 2004

Ran into some bad code from a student of mine, but I was wondering why it doesn't throw an exception about the named variable 'index' being used twice:

code:
if let index = find(self.someArray, someObject) {
    for index in self.someArray {
        
    }
}
Tried another scenario that I thought would throw an exception but doesn't:
code:
for object in self.someArray {
    for object in self.otherArray {
        
    }
}

Volte
Oct 4, 2004

woosh woosh
That's a reasonable thing to do if you don't need to reference the original variable and the new one at the same time (seems like a misunderstanding of how for loops work in this case though). It just shadows the existing variable with a new one with the same name but in a more limited scope. I use it sometimes like this so I don't have to use a ton of extraneous variable names:

code:
// obj: Shape

if let obj = obj as? Rectangle {
  // do stuff with obj which is a Rectangle
} else if let obj = obj as? Circle {
  // do stuff with obj which is a Circle
}
Most languages with block-level variable scoping rules have that feature (i.e. C#, C++)

lord funk
Feb 16, 2004

Wow never noticed that before in any other languages. Thanks for the example, that one makes a lot more sense.

Adbot
ADBOT LOVES YOU

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...

Volte posted:

Most languages with block-level variable scoping rules have that feature (i.e. C#, C++)

C# does not have that "feature". It's a compile error if the same name could refer to two different things in the same scope.

  • Locked thread