Coder Social home page Coder Social logo

Comments (12)

mainjzb avatar mainjzb commented on May 31, 2024

#60720

Similar, except for introduction of new keyword

from go.

bjorndm avatar bjorndm commented on May 31, 2024

Well the main difference is that this doesn't call a function but injects a switch block in predictable locations.

Also this is intended to be purely at compile time only.

from go.

randall77 avatar randall77 commented on May 31, 2024

This makes the question if a variable has a trap or not decidable at compile time.

What about assignments through pointers, and additionally in other functions?

p := &err
if ... { *p = ... }
maybeAssignToArg(p)

from go.

ianlancetaylor avatar ianlancetaylor commented on May 31, 2024

See also #56258.

from go.

bjorndm avatar bjorndm commented on May 31, 2024

Assignments in other functions would not have the trap appended. Assignments through a pointer would but only if the variable named in the trap is a pointer. The trap block is injected only if there is a = or := statement. So @randall77 in your examples no trap block is injected unless if there also is a select block for p. The assignments are though the p variable not through the err variable. Like this this proposal remains a pure compile time text expansion that is easy to understand.

The difference with the other proposal is that the trap is installed explicitly and statically on a named variable, not on the _ variable.

from go.

randall77 avatar randall77 commented on May 31, 2024

So

var err error
select err { ... } // set up a trap
err = ... // this traps
*(&err) = ... // this doesn't trap

?

from go.

bjorndm avatar bjorndm commented on May 31, 2024

That does trap because err is mentioned explicitly. That is the point of this proposal, everything is explicit! :) Of course doing *(&err) is a bit obtuse.

Edit:
And in case err is a struct err.Field = blah does inject the trap since err is mentioned.

from go.

randall77 avatar randall77 commented on May 31, 2024

That does trap because err is mentioned explicitly.

err is mentioned, but there is never an explicit assignment to it. Perhaps this example is better:

p := &err
*p = ...

For extra fun , add arbitrary other complications between the two statements, like

p := &err
if ... { p = ... something else ... }
*p = ...

The general point is that at any pointer assignment, how do you tell whether it is assigning to a trapped variable or not?
I think the only possible answers are "we have to check it at runtime somehow" or "assignments through pointers don't trap".

from go.

bjorndm avatar bjorndm commented on May 31, 2024

Then it is "assignments through pointers don't trap". The idea is that the trap is strictly compile time and nominal only, which makes it a lot simpler to implement than, say, a defer statement for which Go has to keep a runtime list.

As I see it it will still be very useful even with these restrictions.

Edit: this is also how it this proposal is different from simply using a defer() statement for error handling as we can already do with the help of generics e.g. this comment: #57645 (comment)

from go.

zephyrtronium avatar zephyrtronium commented on May 31, 2024

Is the panic here "trapped" or "untrapped"?

var err error
f := func() { err = io.EOF }
select err {
case err != nil:
    panic("trapped")
}
g := func() { err = io.EOF; panic("untrapped") }
f()
g()

Is the panic here 1 or 2? What gets printed before the panic?

var err error
select err {
case err != nil:
    println(1)
    panic(1)
}
select err {
case err != nil:
    println(2)
    panic(2)
}
err = io.EOF

from go.

bjorndm avatar bjorndm commented on May 31, 2024

The anonymous func is a separate scope so untrapped. The second trap block overwrites the first one so for the second example it is 2 only.

from go.

ddkwork avatar ddkwork commented on May 31, 2024
package main

import (
	"reflect"
	"runtime"
	"runtime/debug"
)

func main() {
	c := &Caller{}
	c.call()
}

type Caller struct{}

func (c *Caller) call() {
	Error("this is an error", &c)

	// do not run here
	println(1111)
	println(1111)
	println(1111)
	println(1111)
}

func Error(err any, ptr any) {
	if err == nil {
		return
	}
	debug.PrintStack()
	pc, _, _, _ := runtime.Caller(1)
	fn := runtime.FuncForPC(pc)
	funcName := fn.Name()
	//Is it possible for reflection to dynamically insert a return statement at the next line of code where the parent function calls the sub-function?
	//Also need to assign a value to the return value, not sure of the type
	reflect.Indirect(reflect.ValueOf(ptr)).MethodByName(funcName).Close()
}

from go.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.