A module function can act as a constructor helper when initialization needs a rule before the value is returned.

Program

Play the program to choose the raw port and build a validated server value.

raw_port
constructor_helper.f90
Replay: real traced execution (multi-file project)
module server_model
    implicit none
    type :: server
        character(len=12) :: host
        integer :: port
    end type server
contains
    function make_server(raw_port) result(item)
        integer, intent(in) :: raw_port
        type(server) :: item
        item%host = 'local'
        item%port = max(raw_port, 1)
    end function make_server
end module server_model

program constructor_helper_demo
    use server_model
    implicit none
    integer :: raw_port
    type(server) :: app

    raw_port = 8080
    app = make_server(raw_port)
    print '(A, A, I0)', trim(app%host), ':', app%port
end program constructor_helper_demo
module server_model
    implicit none
    type :: server
        character(len=12) :: host
        integer :: port
    end type server
contains
    function make_server(raw_port) result(item)
        integer, intent(in) :: raw_port
        type(server) :: item
        item%host = 'local'
        item%port = max(raw_port, 1)
    end function make_server
end module server_model

program constructor_helper_demo
    use server_model
    implicit none
    integer :: raw_port
    type(server) :: app

    raw_port = 0
    app = make_server(raw_port)
    print '(A, A, I0)', trim(app%host), ':', app%port
end program constructor_helper_demo
module server_model
    implicit none
    type :: server
        character(len=12) :: host
        integer :: port
    end type server
contains
    function make_server(raw_port) result(item)
        integer, intent(in) :: raw_port
        type(server) :: item
        item%host = 'local'
        item%port = max(raw_port, 1)
    end function make_server
end module server_model

program constructor_helper_demo
    use server_model
    implicit none
    integer :: raw_port
    type(server) :: app

    raw_port = 3000
    app = make_server(raw_port)
    print '(A, A, I0)', trim(app%host), ':', app%port
end program constructor_helper_demo
  1. raw_port ← 8080

    22raw_port = 808023app = make_server(raw_port)
    values this step8080raw_port
  2. app.host ← local, app.port ← 8080

    22raw_port = 808023app = make_server(raw_port)24print '(A, A, I0)', trim(app%host), ':', app%port
    values this steplocalapp.host8080app.port8080raw_port
  3. print '(A, A, I0)', trim(app%host), ':', app%port

    23    app = make_server(raw_port)24    print '(A, A, I0)', trim(app%host), ':', app%port25end program constructor_helper_demo
    outputlocal:8080
    values this steplocalapp.host8080app.port
  1. raw_port ← 0

    22raw_port = 023app = make_server(raw_port)
    values this step0raw_port
  2. app.host ← local, app.port ← 1

    22raw_port = 023app = make_server(raw_port)24print '(A, A, I0)', trim(app%host), ':', app%port
    values this steplocalapp.host1app.port0raw_port
  3. print '(A, A, I0)', trim(app%host), ':', app%port

    23    app = make_server(raw_port)24    print '(A, A, I0)', trim(app%host), ':', app%port25end program constructor_helper_demo
    outputlocal:1
    values this steplocalapp.host1app.port
  1. raw_port ← 3000

    22raw_port = 300023app = make_server(raw_port)
    values this step3000raw_port
  2. app.host ← local, app.port ← 3000

    22raw_port = 300023app = make_server(raw_port)24print '(A, A, I0)', trim(app%host), ':', app%port
    values this steplocalapp.host3000app.port3000raw_port
  3. print '(A, A, I0)', trim(app%host), ':', app%port

    23    app = make_server(raw_port)24    print '(A, A, I0)', trim(app%host), ':', app%port25end program constructor_helper_demo
    outputlocal:3000
    values this steplocalapp.host3000app.port
constructor helper `make_server` returns a fully initialized derived-type value.
component assignment `item%host` and `item%port` assign fields before returning.
validation rule `max(raw_port, 1)` keeps the port positive.