Re: [swift-evolution] [Pitch] Expose assert configuration functions in standard library

2016-06-01 Thread Erica Sadun via swift-evolution

> On Jun 1, 2016, at 9:15 AM, Erica Sadun  wrote:
> 
> Or, to be honest:
> 
> /// Offers user-facing public assert configuration test
> @_transparent
> public
> func isDebugAssertConfiguration() -> Bool {
>   return _isDebugAssertConfiguration()
> }
> 
> which covers, I believe, about 98% of the demand for this feature
> 
> -- E


Following up to myself, now that I'm actually using this, I realize that 
avoiding using a build configuration test might not be the best idea from the 
developer experience side of things: 

main.swift:7:9: warning: will never be executed
print("Not debug assert configuration")
^
main.swift:4:8: note: condition always evaluates to true
if isDebugAssertConfiguration() {
   ^
Testing debug assertion

Whereas going with if #if debugassert() would simply make code "disappear".

-- E

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Expose assert configuration functions in standard library

2016-06-01 Thread Erica Sadun via swift-evolution
Or, to be honest:

/// Offers user-facing public assert configuration test
@_transparent
public
func isDebugAssertConfiguration() -> Bool {
  return _isDebugAssertConfiguration()
}

which covers, I believe, about 98% of the demand for this feature

-- E

> On May 31, 2016, at 11:21 PM, Brent Royal-Gordon  
> wrote:
> 
>> My pitch: I want to promote these three helper functions to the standard 
>> library and remove their underscore prefixes.
> 
> These functions currently have implementations like this:
> 
>   @_transparent
>   @warn_unused_result
>   public // @testable
>   func _isDebugAssertConfiguration() -> Bool {
> // The values for the assert_configuration call are:
> // 0: Debug
> // 1: Release
> // 2: Fast
> return Int32(Builtin.assert_configuration()) == 0
>   }
> 
> I think how this works is:
> 
> * @_transparent makes sure these functions are always inlined at the call 
> site.
> * Most things in the standard library are *also* @_transparent.
> * Therefore, after both (or more!) inlinings happen, you get the 
> `Builtin.assert_configuration()` of the code calling into the standard 
> library.
> 
> Needless to say, this is *extremely* weird and magical, and I'm skeptical of 
> the idea that we should expose it as a normal function call.
> 
> I think a better design which would accurately convey its magic is to add a 
> type to the standard library:
> 
>   enum BuildKind: Int32 { case debug, release, unchecked }
> 
> (Note: the names in this could use some bikeshedding. Put that aside.)
> 
> And then add a `#buildKind` compiler substitution which is equivalent to:
> 
>   BuildKind(rawValue: Int32(Builtin.assert_configuration()))
> 
> Now you can surround your debug-only code with `#buildKind == .debug`. Or you 
> can capture the *call site's* build kind with a default parameter:
> 
>   func log(_ message: String, level: LogLevel = .info, buildKind: 
> BuildKind = #buildKind)
> 
> Even the standard library might be able to do this if it wanted to, allowing 
> your code to enable or disable asserts based on whether your caller's code is 
> in debug mode or not:
> 
>   func assert(@autoclosure condition: () -> Bool, @autoclosure _ message: 
> () -> String = default, file: StaticString= #file, line: UInt = #line, 
> buildKind: BuildKind = #buildKind)
> 
> (I wouldn't suggest that every stdlib member add such a default parameter; 
> most should continue to rely on `@_transparent`. But I think that could be 
> useful for calls like `assert()` and `precondition()`.
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Expose assert configuration functions in standard library

2016-05-31 Thread Brent Royal-Gordon via swift-evolution
> My pitch: I want to promote these three helper functions to the standard 
> library and remove their underscore prefixes.

These functions currently have implementations like this:

@_transparent
@warn_unused_result
public // @testable
func _isDebugAssertConfiguration() -> Bool {
  // The values for the assert_configuration call are:
  // 0: Debug
  // 1: Release
  // 2: Fast
  return Int32(Builtin.assert_configuration()) == 0
}

I think how this works is:

* @_transparent makes sure these functions are always inlined at the call site.
* Most things in the standard library are *also* @_transparent.
* Therefore, after both (or more!) inlinings happen, you get the 
`Builtin.assert_configuration()` of the code calling into the standard library.

Needless to say, this is *extremely* weird and magical, and I'm skeptical of 
the idea that we should expose it as a normal function call.

I think a better design which would accurately convey its magic is to add a 
type to the standard library:

enum BuildKind: Int32 { case debug, release, unchecked }

(Note: the names in this could use some bikeshedding. Put that aside.)

And then add a `#buildKind` compiler substitution which is equivalent to:

BuildKind(rawValue: Int32(Builtin.assert_configuration()))

Now you can surround your debug-only code with `#buildKind == .debug`. Or you 
can capture the *call site's* build kind with a default parameter:

func log(_ message: String, level: LogLevel = .info, buildKind: 
BuildKind = #buildKind)

Even the standard library might be able to do this if it wanted to, allowing 
your code to enable or disable asserts based on whether your caller's code is 
in debug mode or not:

func assert(@autoclosure condition: () -> Bool, @autoclosure _ message: 
() -> String = default, file: StaticString= #file, line: UInt = #line, 
buildKind: BuildKind = #buildKind)

(I wouldn't suggest that every stdlib member add such a default parameter; most 
should continue to rely on `@_transparent`. But I think that could be useful 
for calls like `assert()` and `precondition()`.

-- 
Brent Royal-Gordon
Architechies

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Expose assert configuration functions in standard library

2016-05-29 Thread Jacob Bandes-Storch via swift-evolution
Am I understanding correctly that

-Onone  →  _isDebugAssertConfiguration is true
-O → _isReleaseAssertConfiguration is true
-Ounchecked → _isFastAssertConfiguration is true

?

If the goal is to expose the optimization level to user code, might I
suggest something like

enum OptimizationLevel {
case none
case standard
case unchecked
}

var optimizationLevel: OptimizationLevel { get }

IMO, users may still want to control certain things with per-configuration
flags, but that's still achievable with -DX and #if X. Exposing the
optimization level makes sense to me.

On Sun, May 29, 2016 at 10:59 AM, Erica Sadun via swift-evolution <
swift-evolution@swift.org> wrote:

> Back in March, I somewhat foolishly agreed to pick up the gauntlet for a
> series of community-requested proposals centered on build configurations.
> Requested items included:
>
>
>- A way to test for destination platforms like Apple, Linux,
>Windows, Unix-like, UIKit-supporting, etc
>- A way to test for Simulator/Emulator vs Hardware targets
>- A way to test for debug builds
>- A way to test for platform conditions (bigendian, littlendian,
>bitwidth 32 and 64, objc-interop, see lib/Basic/LangOptions.cpp)
>
>
> This splintered down into a series of draft proposals. The first adopted
> proposal, SE-0075
> 
>  adds
> a build configuration import test similar to Clang's __has_include. It lets
> you test whether a module like UIKit is available, letting you customize
> code for specific modules.
>
> Next up on my list is debug-specific coding. Summarizing to date:
>
>
>- There's a general consensus that a debug state occurs when
>assertions can fire and are not disabled by compile-time optimizations.
>- The concept of "debug" is nuanced enough that introducing a single  #if
>debug build configuration test is insufficient for substantial set of
>community members who interacted in previous discussions and Swift
>developers who have sent me feedback outside this list.
>- Conditioning debug on Xcode debug/release schemes is a no-go.
>- Hidden helper functions already exist in Swift.
>- Members of the core team believe using build configurations is the
>wrong point to conditionalize code.
>
>
> Joe Groff wrote, "We specifically avoided making debug/release an #if
> condition because we considered #if to be the wrong point at which to start
> conditionalizing code generation for assertions. Though the final
> executable image's behavior is unavoidably dependent on whether asserts are
> enabled, we didn't want the SIL for inlineable code to be, since that would
> mean libraries with inlineable code would need to ship three times the
> amount of serialized SIL to support the right behavior in -Onone, -O, and
> -Ounchecked builds. Instead, the standard library has some hidden helper
> functions, _isDebugAssertConfiguration, _isReleaseAssertConfiguration, and
> _isFastAssertConfiguration, which are guaranteed to be constant-folded away
> before final code generation."
>
> My pitch: I want to promote these three helper functions to the standard
> library and remove their underscore prefixes. My primary use case is to
> limit logging and development-servicing functions (for example, statistical
> measurements) to "debug" builds. I believe a sufficient quorum of the
> community has similar needs that would be served by making these first
> class "listed" functions.
>
> Doing so:
>
>
>- Eliminates the build configuration approach
>- Eliminates the need to define what "debug" means
>- Conditions configuration testing on assertion firing state not Xcode
>schemes or build flags (e.g. -D debug)
>- Uses already-existing global functions, requiring no coding
>
>
> Thoughts?
>
> -- E
> p.s. I'd warmly welcome any third party assistance with the outstanding
> requests
>
>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] [Pitch] Expose assert configuration functions in standard library

2016-05-29 Thread Erica Sadun via swift-evolution
Back in March, I somewhat foolishly agreed to pick up the gauntlet for a series 
of community-requested proposals centered on build configurations. Requested 
items included:

A way to test for destination platforms like Apple, Linux, Windows, Unix-like, 
UIKit-supporting, etc
A way to test for Simulator/Emulator vs Hardware targets
A way to test for debug builds
A way to test for platform conditions (bigendian, littlendian, bitwidth 32 and 
64, objc-interop, see lib/Basic/LangOptions.cpp)

This splintered down into a series of draft proposals. The first adopted 
proposal, SE-0075 

 adds a build configuration import test similar to Clang's __has_include. It 
lets you test whether a module like UIKit is available, letting you customize 
code for specific modules.

Next up on my list is debug-specific coding. Summarizing to date:

There's a general consensus that a debug state occurs when assertions can fire 
and are not disabled by compile-time optimizations.
The concept of "debug" is nuanced enough that introducing a single  #if debug 
build configuration test is insufficient for substantial set of community 
members who interacted in previous discussions and Swift developers who have 
sent me feedback outside this list.
Conditioning debug on Xcode debug/release schemes is a no-go.
Hidden helper functions already exist in Swift.
Members of the core team believe using build configurations is the wrong point 
to conditionalize code. 

Joe Groff wrote, "We specifically avoided making debug/release an #if condition 
because we considered #if to be the wrong point at which to start 
conditionalizing code generation for assertions. Though the final executable 
image's behavior is unavoidably dependent on whether asserts are enabled, we 
didn't want the SIL for inlineable code to be, since that would mean libraries 
with inlineable code would need to ship three times the amount of serialized 
SIL to support the right behavior in -Onone, -O, and -Ounchecked builds. 
Instead, the standard library has some hidden helper functions, 
_isDebugAssertConfiguration, _isReleaseAssertConfiguration, and 
_isFastAssertConfiguration, which are guaranteed to be constant-folded away 
before final code generation."

My pitch: I want to promote these three helper functions to the standard 
library and remove their underscore prefixes. My primary use case is to limit 
logging and development-servicing functions (for example, statistical 
measurements) to "debug" builds. I believe a sufficient quorum of the community 
has similar needs that would be served by making these first class "listed" 
functions.

Doing so:

Eliminates the build configuration approach
Eliminates the need to define what "debug" means
Conditions configuration testing on assertion firing state not Xcode schemes or 
build flags (e.g. -D debug)
Uses already-existing global functions, requiring no coding

Thoughts?

-- E
p.s. I'd warmly welcome any third party assistance with the outstanding requests


___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution